migrant 1.1.1 → 1.1.2

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/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2
data/Gemfile CHANGED
@@ -10,4 +10,5 @@ group :development do
10
10
  gem "turn"
11
11
  gem "sqlite3"
12
12
  gem "simplecov"
13
+ gem "terminal-table"
13
14
  end
data/Gemfile.lock CHANGED
@@ -71,6 +71,7 @@ GEM
71
71
  simplecov-html (~> 0.4.0)
72
72
  simplecov-html (0.4.3)
73
73
  sqlite3 (1.3.3)
74
+ terminal-table (1.4.2)
74
75
  thor (0.14.6)
75
76
  thoughtbot-shoulda (2.11.1)
76
77
  treetop (1.4.9)
@@ -89,5 +90,6 @@ DEPENDENCIES
89
90
  rails (>= 3.0.0)
90
91
  simplecov
91
92
  sqlite3
93
+ terminal-table
92
94
  thoughtbot-shoulda
93
95
  turn
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.1
1
+ 1.1.2
@@ -62,18 +62,24 @@ module DataType
62
62
 
63
63
  def self.migrant_data_type?; true; end
64
64
  end
65
+
66
+
65
67
  end
66
68
 
67
- # And all the data types we offer...
68
- require 'datatype/boolean'
69
- require 'datatype/currency'
70
- require 'datatype/date'
71
- require 'datatype/fixnum'
72
- require 'datatype/float'
73
- require 'datatype/foreign_key'
74
- require 'datatype/polymorphic'
75
- require 'datatype/range'
76
- require 'datatype/string'
77
- require 'datatype/symbol'
78
- require 'datatype/time'
69
+ require 'dsl/data_types/primitives'
70
+ require 'dsl/data_types/semantic'
79
71
 
72
+ # Add internal types used by Migrant
73
+ module DataType
74
+ class Polymorphic < Base; end
75
+
76
+ class ForeignKey < Fixnum
77
+ def column
78
+ {:type => :integer}
79
+ end
80
+
81
+ def self.default_mock
82
+ nil # Will get overridden later by ModelExtensions
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,106 @@
1
+ module DataType
2
+ # Boolean
3
+ class TrueClass < Base
4
+ def column
5
+ {:type => :boolean}
6
+ end
7
+
8
+ def self.default_mock
9
+ true
10
+ end
11
+ end
12
+
13
+ class FalseClass < TrueClass; end;
14
+
15
+ # Datetime
16
+ class Date < Base
17
+ def column
18
+ {:type => :datetime}
19
+ end
20
+
21
+ def self.default_mock
22
+ ::Time.now
23
+ end
24
+ end
25
+
26
+ class Time < Date; end; # No different to date type
27
+
28
+ # Integers
29
+ class Fixnum < Base
30
+ def column
31
+ {:type => :integer}.tap do |options|
32
+ options.merge!(:limit => @value.size) if @value > 2147483647 # 32-bit limit. Not checking size here because a 64-bit OS always has at least 8 byte size
33
+ end
34
+ end
35
+
36
+ def self.default_mock
37
+ rand(999999).to_i
38
+ end
39
+ end
40
+
41
+ class Bignum < Fixnum
42
+ def column
43
+ {:type => :integer, :limit => ((@value.size > 8)? @value.size : 8) }
44
+ end
45
+ end
46
+
47
+ class Float < Base
48
+ def column
49
+ {:type => :float}
50
+ end
51
+
52
+ def self.default_mock
53
+ rand(100).to_f-55.0
54
+ end
55
+ end
56
+
57
+ # Range (0..10)
58
+ class Range < Base
59
+ def column
60
+ definition = {:type => :integer}
61
+ definition[:limit] = @value.max.to_s.length if @value.respond_to?(:max)
62
+ definition
63
+ end
64
+ end
65
+
66
+ # Strings
67
+ class String < Base
68
+ def initialize(options)
69
+ super(options)
70
+ @value ||= ''
71
+ end
72
+
73
+ def column
74
+ if @value.match(/[\d,]+\.\d{2}$/)
75
+ return Currency.new(@options).column
76
+ else
77
+ return @value.match(/[\r\n\t]/)? { :type => :text }.merge(@options) : super
78
+ end
79
+ end
80
+
81
+ def mock
82
+ @value || ((self.column[:type] == :text)? self.class.long_text_mock : self.class.default_mock )
83
+ end
84
+ end
85
+
86
+ # Symbol (defaults, specified by user)
87
+ class Symbol < Base
88
+ def column
89
+ # Just construct whatever the user wants
90
+ {:type => @value || :string }.merge(@options)
91
+ end
92
+
93
+ def mock
94
+ case @value || :string
95
+ when :text then self.class.long_text_mock
96
+ when :string then self.class.short_text_mock
97
+ when :integer then Fixnum.default_mock
98
+ when :decimal, :float then Float.default_mock
99
+ when :datetime, :date then Date.default_mock
100
+ end
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+
@@ -0,0 +1,22 @@
1
+ class <%= @activity.camelize.gsub(/\s/, '') %> < ActiveRecord::Migration
2
+ def self.up
3
+ <% @added_columns.each do |field, options| %>
4
+ add_column :<%= @table_name %>, :<%= field %>, :<%= options.delete(:type) %><%= (options.blank?)? '': ", "+options.inspect[1..-2] %>
5
+ <% end -%>
6
+ <% @changed_columns.each do |field, options, old_options| %>
7
+ change_column :<%= @table_name %>, :<%= field %>, :<%= options.delete(:type) %><%= (options.blank?)? '': ", "+options.inspect[1..-2] %>
8
+ <% end -%>
9
+ <% @indexes.each do |index, options| %>
10
+ add_index :<%= @table_name %>, <%= index.inspect %>
11
+ <% end -%>
12
+ end
13
+
14
+ def self.down
15
+ <% @added_columns.each do |field, options| %>
16
+ remove_column :<%= @table_name %>, :<%= field %>
17
+ <% end -%>
18
+ <% @changed_columns.each do |field, options, old_options| %>
19
+ change_column :<%= @table_name %>, :<%= field %>, :<%= old_options.delete(:type) %><%= (old_options.blank?)? '': ", "+old_options.inspect[1..-2] %>
20
+ <% end -%>
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ class <%= @activity.camelize.gsub(/\s/, '') %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= @table_name %> do |t|
4
+ <% @columns.each do |field, options| %>
5
+ t.<%= options.delete(:type) %> :<%= field %><%= (options.blank?)? '': ", "+options.inspect[1..-2] %>
6
+ <% end %>
7
+ end
8
+ <% @indexes.each do |index| %>
9
+ add_index :<%= @table_name %>, <%= index.inspect %>
10
+ <% end -%>
11
+ end
12
+
13
+ def self.down
14
+ drop_table :<%= @table_name %>
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ class <%= @activity.camelize.gsub(/\s/, '') %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= @table_name %> do |t|
4
+ <% @columns.each do |field, options| %>
5
+ t.<%= options.delete(:type) %> :<%= field %><%= (options.blank?)? '': ", "+options.inspect[1..-2] %>
6
+ <% end %>
7
+ end
8
+ <% @indexes.each do |index, options| %>
9
+ add_index :<%= @table_name %>, <%= index.inspect %>
10
+ <% end -%>
11
+ end
12
+
13
+ def self.down
14
+ drop_table :<%= @table_name %>
15
+ end
16
+ end
@@ -1,3 +1,5 @@
1
+ require 'erubis'
2
+
1
3
  module Migrant
2
4
  class MigrationGenerator
3
5
  TABS = ' ' # Tabs to spaces * 2
@@ -21,79 +23,52 @@ module Migrant
21
23
  ActiveRecord::Base.descendants.each do |model|
22
24
  next if model.schema.nil? || !model.schema.requires_migration? # Skips inherited schemas (such as models with STI)
23
25
  model.reset_column_information # db:migrate doesn't do this
24
- model_schema = model.schema.column_migrations
26
+ @table_name = model.table_name
25
27
 
26
28
  if model.table_exists?
27
29
  # Structure ActiveRecord::Base's column information so we can compare it directly to the schema
28
30
  db_schema = Hash[*model.columns.collect {|c| [c.name.to_sym, Hash[*[:type, :limit].map { |type| [type, c.send(type)] }.flatten] ] }.flatten]
29
- changes = model.schema.columns.collect do |name, data_type|
30
- begin
31
- [name, data_type.structure_changes_from(db_schema[name])]
32
- rescue DataType::DangerousMigration
33
- puts "Cannot generate migration automatically for #{model.table_name}, this would involve possible data loss on column: #{name}\nOld structure: #{db_schema[name].inspect}. New structure: #{data_type.column.inspect}\nPlease create and run this migration yourself (with the appropriate data integrity checks)"
34
- return false
35
- end
36
- end.reject { |change| change[1].nil? }
37
- next if changes.blank?
38
- changed_fields, added_fields = [], []
39
-
40
- up_code = changes.collect do |field, options|
41
- type = options.delete(:type)
42
- arguments = (options.blank?)? "" : ", #{options.inspect[1..-2]}"
43
-
44
- if db_schema[field]
45
- changed_fields << field
46
- "change_column :#{model.table_name}, :#{field}, :#{type}#{arguments}"
47
- else
48
- added_fields << field
49
- "add_column :#{model.table_name}, :#{field}, :#{type}#{arguments}"
50
- end
51
- end.join(NEWLINE+TABS)
52
-
53
- activity = 'changed_'+model.table_name+[(added_fields.blank?)? nil : '_added_'+added_fields.join('_'), (changed_fields.blank?)? nil : '_modified_'+changed_fields.join('_')].compact.join('_and_')
54
-
55
- down_code = changes.collect do |field, options|
56
- if db_schema[field]
57
- type = db_schema[field].delete(:type)
58
- arguments = (db_schema[field].blank?)? "" : ", #{db_schema[field].inspect[1..-2]}"
59
- "change_column :#{model.table_name}, :#{field}, :#{type}#{arguments}"
60
- else
61
- "remove_column :#{model.table_name}, :#{field}"
62
- end
63
- end.join(NEWLINE+TABS)
64
-
65
- # For adapters that can report indexes, add as necessary
66
- if ActiveRecord::Base.connection.respond_to?(:indexes)
67
- current_indexes = ActiveRecord::Base.connection.indexes(model.table_name).collect { |index| (index.columns.length == 1)? index.columns.first.to_sym : index.columns.collect(&:to_sym) }
68
- up_code += model.schema.indexes.uniq.collect do |index|
69
- unless current_indexes.include?(index)
70
- NEWLINE+TABS+"add_index :#{model.table_name}, #{index.inspect}"
31
+ @changed_columns, @added_columns = [], []
32
+ model.schema.columns.to_a.sort { |a,b| a.to_s <=> b.to_s }.each do |field_name, data_type|
33
+ begin
34
+ if (options = data_type.structure_changes_from(db_schema[field_name]))
35
+ if db_schema[field_name]
36
+ @changed_columns << [field_name, options, db_schema[field_name]]
37
+ else
38
+ @added_columns << [field_name, options]
71
39
  end
72
- end.compact.join
40
+ end
41
+ rescue DataType::DangerousMigration
42
+ puts "Cannot generate migration automatically for #{model.table_name}, this would involve possible data loss on column: #{field_name}\nOld structure: #{db_schema[field_name].inspect}. New structure: #{data_type.column.inspect}\nPlease create and run this migration yourself (with the appropriate data integrity checks)"
43
+ return false
73
44
  end
45
+ end
46
+
47
+ # For adapters that can report indexes, add as necessary
48
+ if ActiveRecord::Base.connection.respond_to?(:indexes)
49
+ current_indexes = ActiveRecord::Base.connection.indexes(model.table_name).collect { |index| (index.columns.length == 1)? index.columns.first.to_sym : index.columns.collect(&:to_sym) }
50
+ @indexes = model.schema.indexes.uniq.reject { |index| current_indexes.include?(index) }.collect { |field_name| [field_name, {}] }
51
+ # Don't spam the user with indexes that columns are being created with
52
+ @new_indexes = @indexes.reject { |index, options| @changed_columns.detect { |c| c.first == index } || @added_columns.detect { |c| c.first == index } }
53
+ end
54
+
55
+ next if @changed_columns.empty? && @added_columns.empty? && @indexes.empty? # Nothing to do for this table
56
+
57
+ # Example: changed_table_added_something_and_modified_something
58
+ @activity = 'changed_'+model.table_name+[['added', @added_columns], ['modified', @changed_columns], ['indexed', @new_indexes]].reject { |v| v[1].empty? }.collect { |v| "_#{v[0]}_"+v[1].collect(&:first).join('_') }.join('_and')
59
+ @activity = @activity.split('_')[0..2].join('_') if @activity.length >= 240 # Most filesystems will raise Errno::ENAMETOOLONG otherwise
60
+
61
+ render('change_migration')
74
62
  else
75
- activity = "create_#{model.table_name}"
76
- up_code = "create_table :#{model.table_name} do |t|"+NEWLINE+model_schema.collect do |field, options|
77
- type = options.delete(:type)
78
- options.delete(:was) # Aliases not relevant when creating a new table
79
- arguments = (options.blank?)? "" : ", #{options.inspect[1..-2]}"
80
- (TABS*2)+"t.#{type} :#{field}#{arguments}"
81
- end.join(NEWLINE)+NEWLINE+TABS+"end"
63
+ @activity = "create_#{model.table_name}"
64
+ @columns = model.schema.column_migrations
65
+ @indexes = model.schema.indexes
82
66
 
83
- down_code = "drop_table :#{model.table_name}"
84
- up_code += NEWLINE+TABS+model.schema.indexes.collect { |fields| "add_index :#{model.table_name}, #{fields.inspect}"}.join(NEWLINE+TABS)
85
- end
86
-
87
- # Indexes
88
- # down_code += NEWLINE+TABS+model.schema.indexes.collect { |fields| "remove_index :#{model.table_name}, #{fields.inspect}"}.join(NEWLINE+TABS)
89
- begin
90
- filename = "#{migrations_path}/#{next_migration_number}_#{activity}.rb"
91
- File.open(filename, 'w') { |migration| migration.write(migration_template(activity, up_code, down_code)) }
92
- rescue Errno::ENAMETOOLONG
93
- activity = activity.split('_')[0..2].join('_')
94
- filename = "#{migrations_path}/#{next_migration_number}_#{activity}.rb"
95
- File.open(filename, 'w') { |migration| migration.write(migration_template(activity, up_code, down_code)) }
67
+ render("create_migration")
96
68
  end
69
+
70
+ filename = "#{migrations_path}/#{next_migration_number}_#{@activity}.rb"
71
+ File.open(filename, 'w') { |migration| migration.write(@output) }
97
72
  puts "Wrote #{filename}..."
98
73
  end
99
74
  true
@@ -121,16 +96,8 @@ module Migrant
121
96
  end
122
97
  end
123
98
 
124
- def migration_template(activity, up_code, down_code)
125
- "class #{activity.camelize.gsub(/\s/, '')} < ActiveRecord::Migration
126
- def self.up
127
- #{up_code}
128
- end
129
-
130
- def self.down
131
- #{down_code}
132
- end
133
- end"
99
+ def render(template_name)
100
+ @output = Erubis::Eruby.new(File.read(File.join(File.dirname(__FILE__), "../generators/templates/#{template_name}.erb"))).result(binding)
134
101
  end
135
102
  end
136
103
  end
@@ -11,17 +11,17 @@ module Migrant
11
11
  # into a schema on that model class by calling method_missing(my_field)
12
12
  # and deciding what the best schema type is for the user's requiredments
13
13
  class Schema
14
- attr_accessor :indexes, :columns, :validations, :methods_to_alias
14
+ attr_accessor :indexes, :columns, :validations
15
15
 
16
16
  def initialize
17
17
  @proxy = SchemaProxy.new(self)
18
18
  @columns = Hash.new
19
19
  @indexes = Array.new
20
20
  @validations = Hash.new
21
- @methods_to_alias = Array.new
22
21
  end
23
22
 
24
23
  def define_structure(&block)
24
+ @validations = Hash.new
25
25
  # Runs method_missing on columns given in the model "structure" DSL
26
26
  @proxy.translate_fancy_dsl(&block) if block_given?
27
27
  end
@@ -56,7 +56,8 @@ module Migrant
56
56
 
57
57
  def add_field(field, data_type = nil, options = {})
58
58
  data_type = DataType::String if data_type.nil?
59
-
59
+ puts [":#{field}", "#{data_type}", "#{options.inspect}"].collect { |s| s.ljust(25) }.join if ENV['DEBUG']
60
+
60
61
  # Fields that do special things go here.
61
62
  if field == :timestamps
62
63
  add_field(:updated_at, :datetime)
@@ -83,8 +84,8 @@ module Migrant
83
84
  @columns[field] = DataType::Base.new(options)
84
85
  end
85
86
  end
86
- puts [":#{field}", "#{@columns[field].class}", "#{options.inspect}"].collect { |s| s.ljust(25) }.join if ENV['DEBUG']
87
87
  end
88
+
88
89
  end
89
90
 
90
91
  class InheritedSchema < Schema
data/lib/migrant.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'active_support'
2
2
  require 'active_record'
3
- require 'datatype/base'
3
+ require 'dsl/data_type'
4
4
  require 'migrant/schema'
5
5
  require 'migrant/model_extensions'
6
6
  require 'migrant/migration_generator'
data/migrant.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{migrant}
8
- s.version = "1.1.1"
8
+ s.version = "1.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Pascal Houliston"]
12
- s.date = %q{2011-04-01}
12
+ s.date = %q{2011-04-12}
13
13
  s.description = %q{Easier schema management for Rails that compliments your domain model.}
14
14
  s.email = %q{101pascal@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -17,26 +17,21 @@ Gem::Specification.new do |s|
17
17
  "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
+ ".rvmrc",
20
21
  "Gemfile",
21
22
  "Gemfile.lock",
22
23
  "LICENSE",
23
24
  "README.rdoc",
24
25
  "Rakefile",
25
26
  "VERSION",
26
- "lib/datatype/base.rb",
27
- "lib/datatype/boolean.rb",
28
- "lib/datatype/currency.rb",
29
- "lib/datatype/date.rb",
30
- "lib/datatype/fixnum.rb",
31
- "lib/datatype/float.rb",
32
- "lib/datatype/foreign_key.rb",
33
- "lib/datatype/polymorphic.rb",
34
- "lib/datatype/range.rb",
35
- "lib/datatype/string.rb",
36
- "lib/datatype/symbol.rb",
37
- "lib/datatype/time.rb",
27
+ "lib/dsl/data_type.rb",
28
+ "lib/dsl/data_types/primitives.rb",
29
+ "lib/dsl/data_types/semantic.rb",
38
30
  "lib/generators/migrations.rb",
39
31
  "lib/generators/model.rb",
32
+ "lib/generators/templates/change_migration.erb",
33
+ "lib/generators/templates/create_migration.erb",
34
+ "lib/generators/templates/create_migration.rb",
40
35
  "lib/generators/templates/model.rb",
41
36
  "lib/migrant.rb",
42
37
  "lib/migrant/migration_generator.rb",
@@ -87,6 +82,7 @@ Gem::Specification.new do |s|
87
82
  "test/test_data_schema.rb",
88
83
  "test/test_migration_generator.rb",
89
84
  "test/test_validations.rb",
85
+ "test/test_zzz_performance.rb",
90
86
  "test/verified_output/migrations/business_id.rb",
91
87
  "test/verified_output/migrations/create_business_categories.rb",
92
88
  "test/verified_output/migrations/create_businesses.rb",
@@ -129,6 +125,7 @@ Gem::Specification.new do |s|
129
125
  "test/test_data_schema.rb",
130
126
  "test/test_migration_generator.rb",
131
127
  "test/test_validations.rb",
128
+ "test/test_zzz_performance.rb",
132
129
  "test/verified_output/migrations/business_id.rb",
133
130
  "test/verified_output/migrations/create_business_categories.rb",
134
131
  "test/verified_output/migrations/create_businesses.rb",
@@ -152,6 +149,7 @@ Gem::Specification.new do |s|
152
149
  s.add_development_dependency(%q<turn>, [">= 0"])
153
150
  s.add_development_dependency(%q<sqlite3>, [">= 0"])
154
151
  s.add_development_dependency(%q<simplecov>, [">= 0"])
152
+ s.add_development_dependency(%q<terminal-table>, [">= 0"])
155
153
  else
156
154
  s.add_dependency(%q<rails>, [">= 3.0.0"])
157
155
  s.add_dependency(%q<faker>, [">= 0"])
@@ -161,6 +159,7 @@ Gem::Specification.new do |s|
161
159
  s.add_dependency(%q<turn>, [">= 0"])
162
160
  s.add_dependency(%q<sqlite3>, [">= 0"])
163
161
  s.add_dependency(%q<simplecov>, [">= 0"])
162
+ s.add_dependency(%q<terminal-table>, [">= 0"])
164
163
  end
165
164
  else
166
165
  s.add_dependency(%q<rails>, [">= 3.0.0"])
@@ -171,6 +170,7 @@ Gem::Specification.new do |s|
171
170
  s.add_dependency(%q<turn>, [">= 0"])
172
171
  s.add_dependency(%q<sqlite3>, [">= 0"])
173
172
  s.add_dependency(%q<simplecov>, [">= 0"])
173
+ s.add_dependency(%q<terminal-table>, [">= 0"])
174
174
  end
175
175
  end
176
176
 
data/test/helper.rb CHANGED
@@ -17,14 +17,36 @@ require 'rubygems'
17
17
  require 'turn' # For nicer output
18
18
  require 'test/unit'
19
19
  require 'shoulda'
20
+ require 'terminal-table/import'
20
21
 
21
22
  # Must be loaded before appropriate models so we get class method extensions
22
23
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
23
24
  $LOAD_PATH.unshift(File.dirname(__FILE__))
24
25
 
25
-
26
26
  require 'migrant'
27
27
 
28
+ class Profiler
29
+ @@results = {}
30
+
31
+ def self.run(name, &block)
32
+ start = Time.now.to_f
33
+ yield
34
+ @@results[name] ||= {:total => 0.0, :calls => 0}
35
+ @@results[name][:total] += Time.now.to_f - start
36
+ @@results[name][:calls] += 1
37
+ end
38
+
39
+ def self.results
40
+ unless @@results.keys.empty?
41
+ results = table do |t|
42
+ t.headings = ['Name', 'Calls', 'Total (ms)', 'Average (ms)']
43
+ @@results.collect { |name, result| [name, result[:calls], (result[:total]*1000.0).round, (result[:total] / result[:calls] * 1000.0).round] }.each { |row| t << row }
44
+ end
45
+ puts results
46
+ end
47
+ end
48
+ end
49
+
28
50
  # Reset database
29
51
  db_path = File.join(File.dirname(__FILE__), 'rails_app', 'db', 'test.sqlite3')
30
52
  File.delete(db_path) if File.exists?(db_path)
@@ -38,3 +60,4 @@ require File.join(File.dirname(__FILE__), 'rails_app', 'config', 'environment')
38
60
 
39
61
  class Test::Unit::TestCase
40
62
  end
63
+
@@ -5,5 +5,6 @@ class Category < ActiveRecord::Base
5
5
  structure do
6
6
  title :index => true # Default type is a good 'ol varchar(255)
7
7
  summary
8
+ serial_number 1234567891011121314
8
9
  end
9
10
  end
@@ -33,6 +33,10 @@ class TestDataSchema < Test::Unit::TestCase
33
33
  should "generate a smallint column when given a small range" do
34
34
  assert_schema(Business, :operating_days, :limit => 1, :type => :integer)
35
35
  end
36
+
37
+ should "generate a large integer (size 8) for any bignum types" do
38
+ assert_schema(Category, :serial_number, :limit => 8, :type => :integer)
39
+ end
36
40
 
37
41
  should "generate a string column when given a sentence" do
38
42
  assert_schema(Business, :summary, :type => :string)
@@ -7,10 +7,15 @@ def rake_migrate
7
7
  end
8
8
  end
9
9
 
10
-
11
10
  class TestMigrationGenerator < Test::Unit::TestCase
11
+ def generate_migrations
12
+ Profiler.run(:migration_generator) do
13
+ assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
14
+ end
15
+ end
16
+
12
17
  def run_against_template(template)
13
- assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
18
+ generate_migrations
14
19
  Dir.glob(File.join(File.dirname(__FILE__), 'rails_app', 'db' ,'migrate', '*.rb')).each do |migration_file|
15
20
  if migration_file.include?(template)
16
21
  to_test = File.open(migration_file, 'r') { |r| r.read}.strip
@@ -28,7 +33,7 @@ class TestMigrationGenerator < Test::Unit::TestCase
28
33
 
29
34
  context "The migration generator" do
30
35
  should "create migrations for all new tables" do
31
- assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
36
+ generate_migrations
32
37
  Dir.glob(File.join(File.dirname(__FILE__), 'rails_app', 'db' ,'migrate', '*.rb')).each do |migration_file|
33
38
  to_test = File.open(migration_file, 'r') { |r| r.read}.strip
34
39
  File.open(File.join(File.dirname(__FILE__), 'verified_output', 'migrations', migration_file.sub(/^.*\d+_/, '')), 'r') do |file|
@@ -95,7 +100,7 @@ class TestMigrationGenerator < Test::Unit::TestCase
95
100
  end
96
101
  # Remove migrations
97
102
  ActiveRecord::Base.timestamped_migrations = false
98
- assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
103
+ generate_migrations
99
104
  ActiveRecord::Base.timestamped_migrations = true
100
105
 
101
106
  assert_equal(Dir.glob(File.join(File.dirname(__FILE__), 'rails_app', 'db' ,'migrate', '*.rb')).select { |migration_file| migration_file.include?('new_field_i_made_up') }.length,
@@ -115,7 +120,7 @@ class TestMigrationGenerator < Test::Unit::TestCase
115
120
  end
116
121
 
117
122
  BusinessCategory.belongs_to(:notaclass, :polymorphic => true)
118
- assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
123
+ generate_migrations
119
124
  rake_migrate
120
125
  BusinessCategory.reset_column_information
121
126
  BusinessCategory.mock!
@@ -144,7 +149,7 @@ class TestMigrationGenerator < Test::Unit::TestCase
144
149
  end
145
150
 
146
151
  BusinessCategory.belongs_to(:verylongclassthatissuretogenerateaverylargeoutputfilename, :polymorphic => true)
147
- assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
152
+ generate_migrations
148
153
  rake_migrate
149
154
  end
150
155
  end
@@ -0,0 +1,13 @@
1
+ require 'helper'
2
+
3
+ #SimpleProfiler.results
4
+
5
+ class TestZZZPerformance < Test::Unit::TestCase
6
+ context "Performance" do
7
+ should "be within acceptable limits" do
8
+ # Just a utility test for printing profiler results
9
+ Profiler.results
10
+ assert true
11
+ end
12
+ end
13
+ end
@@ -1,4 +1,4 @@
1
- class ChangedBusinessesAddedUpdatedAtCreatedAt < ActiveRecord::Migration
1
+ class ChangedBusinessesAddedCreatedAtUpdatedAt < ActiveRecord::Migration
2
2
  def self.up
3
3
  add_column :businesses, :updated_at, :datetime
4
4
  add_column :businesses, :created_at, :datetime
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: migrant
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.1.1
5
+ version: 1.1.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Pascal Houliston
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-01 00:00:00 +02:00
13
+ date: 2011-04-12 00:00:00 +00:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -101,6 +101,17 @@ dependencies:
101
101
  type: :development
102
102
  prerelease: false
103
103
  version_requirements: *id008
104
+ - !ruby/object:Gem::Dependency
105
+ name: terminal-table
106
+ requirement: &id009 !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: "0"
112
+ type: :development
113
+ prerelease: false
114
+ version_requirements: *id009
104
115
  description: Easier schema management for Rails that compliments your domain model.
105
116
  email: 101pascal@gmail.com
106
117
  executables: []
@@ -111,26 +122,21 @@ extra_rdoc_files:
111
122
  - LICENSE
112
123
  - README.rdoc
113
124
  files:
125
+ - .rvmrc
114
126
  - Gemfile
115
127
  - Gemfile.lock
116
128
  - LICENSE
117
129
  - README.rdoc
118
130
  - Rakefile
119
131
  - VERSION
120
- - lib/datatype/base.rb
121
- - lib/datatype/boolean.rb
122
- - lib/datatype/currency.rb
123
- - lib/datatype/date.rb
124
- - lib/datatype/fixnum.rb
125
- - lib/datatype/float.rb
126
- - lib/datatype/foreign_key.rb
127
- - lib/datatype/polymorphic.rb
128
- - lib/datatype/range.rb
129
- - lib/datatype/string.rb
130
- - lib/datatype/symbol.rb
131
- - lib/datatype/time.rb
132
+ - lib/dsl/data_type.rb
133
+ - lib/dsl/data_types/primitives.rb
134
+ - lib/dsl/data_types/semantic.rb
132
135
  - lib/generators/migrations.rb
133
136
  - lib/generators/model.rb
137
+ - lib/generators/templates/change_migration.erb
138
+ - lib/generators/templates/create_migration.erb
139
+ - lib/generators/templates/create_migration.rb
134
140
  - lib/generators/templates/model.rb
135
141
  - lib/migrant.rb
136
142
  - lib/migrant/migration_generator.rb
@@ -181,6 +187,7 @@ files:
181
187
  - test/test_data_schema.rb
182
188
  - test/test_migration_generator.rb
183
189
  - test/test_validations.rb
190
+ - test/test_zzz_performance.rb
184
191
  - test/verified_output/migrations/business_id.rb
185
192
  - test/verified_output/migrations/create_business_categories.rb
186
193
  - test/verified_output/migrations/create_businesses.rb
@@ -204,7 +211,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
204
211
  requirements:
205
212
  - - ">="
206
213
  - !ruby/object:Gem::Version
207
- hash: -2795285372725483730
214
+ hash: 146286865
208
215
  segments:
209
216
  - 0
210
217
  version: "0"
@@ -249,6 +256,7 @@ test_files:
249
256
  - test/test_data_schema.rb
250
257
  - test/test_migration_generator.rb
251
258
  - test/test_validations.rb
259
+ - test/test_zzz_performance.rb
252
260
  - test/verified_output/migrations/business_id.rb
253
261
  - test/verified_output/migrations/create_business_categories.rb
254
262
  - test/verified_output/migrations/create_businesses.rb
@@ -1,15 +0,0 @@
1
- module DataType
2
- class TrueClass < Base
3
- def column
4
- {:type => :boolean}
5
- end
6
-
7
- def self.default_mock
8
- true
9
- end
10
- end
11
-
12
- class FalseClass < TrueClass; end;
13
- end
14
-
15
-
data/lib/datatype/date.rb DELETED
@@ -1,13 +0,0 @@
1
- module DataType
2
- class Date < Base
3
- def column
4
- {:type => :datetime}
5
- end
6
-
7
- def self.default_mock
8
- ::Time.now
9
- end
10
- end
11
- end
12
-
13
-
@@ -1,13 +0,0 @@
1
- module DataType
2
- class Fixnum < Base
3
- def column
4
- {:type => :integer}.tap do |options|
5
- options.merge!(:limit => @value.size) if @value > 2147483647 # 32-bit limit. Not checking size here because a 64-bit OS always has at least 8 byte size
6
- end
7
- end
8
-
9
- def self.default_mock
10
- rand(999999).to_i
11
- end
12
- end
13
- end
@@ -1,11 +0,0 @@
1
- module DataType
2
- class Float < Base
3
- def column
4
- {:type => :float}
5
- end
6
-
7
- def self.default_mock
8
- rand(100).to_f-55.0
9
- end
10
- end
11
- end
@@ -1,13 +0,0 @@
1
- module DataType
2
- class ForeignKey < Base
3
- def column
4
- {:type => :integer}
5
- end
6
-
7
- def self.default_mock
8
- nil # Will get overridden later by ModelExtensions
9
- end
10
- end
11
- end
12
-
13
-
@@ -1,8 +0,0 @@
1
- module DataType
2
- class Polymorphic < Base
3
- def mock
4
- # Eek, can't mock an unknown type
5
- nil
6
- end
7
- end
8
- end
@@ -1,9 +0,0 @@
1
- module DataType
2
- class Range < Base
3
- def column
4
- definition = {:type => :integer}
5
- definition[:limit] = @value.max.to_s.length if @value.respond_to?(:max)
6
- definition
7
- end
8
- end
9
- end
@@ -1,22 +0,0 @@
1
- module DataType
2
- class String < Base
3
- def initialize(options)
4
- super(options)
5
- @value ||= ''
6
- end
7
-
8
- def column
9
- if @value.match(/[\d,]+\.\d{2}$/)
10
- return Currency.new(@options).column
11
- else
12
- return @value.match(/[\r\n\t]/)? { :type => :text }.merge(@options) : super
13
- end
14
- end
15
-
16
- def mock
17
- @value || ((self.column[:type] == :text)? self.class.long_text_mock : self.class.default_mock )
18
- end
19
- end
20
- end
21
-
22
-
@@ -1,20 +0,0 @@
1
- module DataType
2
- class Symbol < Base
3
- def column
4
- # Just construct whatever the user wants
5
- {:type => @value || :string }.merge(@options)
6
- end
7
-
8
- def mock
9
- case @value || :string
10
- when :text then self.class.long_text_mock
11
- when :string then self.class.short_text_mock
12
- when :integer then Fixnum.default_mock
13
- when :decimal, :float then Float.default_mock
14
- when :datetime, :date then Date.default_mock
15
- end
16
- end
17
- end
18
- end
19
-
20
-
data/lib/datatype/time.rb DELETED
@@ -1,5 +0,0 @@
1
- module DataType
2
- class Time < Date
3
- # No different to date type
4
- end
5
- end