migrant 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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