ensured_schema 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,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ensured_schema.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ensured_schema/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ensured_schema"
7
+ s.version = EnsuredSchema::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Chris Conley"]
10
+ s.email = ["chris@chrisconley.me"]
11
+ s.homepage = "http://rubygems.org/gems/ensured_schema"
12
+ s.summary = %q{Ensures database schema always matches your schema.rb file}
13
+ s.description = %q{Smarter migrations}
14
+
15
+ s.rubyforge_project = "ensured_schema"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,3 @@
1
+ module EnsuredSchema
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,155 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class AbstractAdapter
4
+ def table_exists?(table_name)
5
+ tables.map(&:downcase).include?(table_name.to_s.downcase)
6
+ end
7
+ end
8
+
9
+ module SchemaStatements
10
+ # Checks to see if a column exists in a given table.
11
+ #
12
+ # === Examples
13
+ # # Check a column exists
14
+ # column_exists?(:suppliers, :name)
15
+ #
16
+ # # Check a column exists of a particular type
17
+ # column_exists?(:suppliers, :name, :string)
18
+ #
19
+ # # Check a column exists with a specific definition
20
+ # column_exists?(:suppliers, :name, :string, :limit => 100)
21
+ def column_exists?(table_name, column_name, type = nil, options = {})
22
+ #debugger
23
+ columns(table_name).any?{ |c| c.name == column_name.to_s &&
24
+ (!type || c.type.to_s == type.to_s) &&
25
+ (!options[:limit] || c.limit_exists?(options[:limit])) &&
26
+ (!options[:precision] || c.precision == options[:precision]) &&
27
+ (!options[:scale] || c.scale == options[:scale]) }
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ module ActiveRecord
34
+ module ConnectionAdapters
35
+ class Column
36
+ def limit_exists?(new_limit)
37
+ self.limit == new_limit
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ module ActiveRecord
44
+ module ConnectionAdapters
45
+ class MysqlColumn
46
+ def limit_exists?(new_limit)
47
+ return super unless type.to_s == 'integer'
48
+ case new_limit
49
+ when 5..8
50
+ self.limit == 8
51
+ when nil, 4, 11
52
+ self.limit == 4
53
+ else
54
+ self.limit == new_limit
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+
62
+ module ActiveRecord
63
+ module ConnectionAdapters
64
+ class EnsuredTable < Table
65
+
66
+ def column_exists?(column_name, type = nil, options = {})
67
+ #debugger
68
+ @base.column_exists?(@table_name, column_name, type, options)
69
+ end
70
+
71
+ %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
72
+ class_eval <<-EOV
73
+ def #{column_type}(*args) # def string(*args)
74
+ define_columns('#{column_type}', *args) # define_column('string', *args)
75
+ end # end
76
+ EOV
77
+ end
78
+
79
+ def define_columns(column_type, *args)
80
+ options = args.extract_options!
81
+ column_names = args
82
+
83
+ column_names.each do |name|
84
+ column_def = build_column_definition(name, column_type, options)
85
+ def_options = column_def.members.inject({}){|h, k| h[k.to_sym] = column_def[k]; h;}
86
+ #debugger
87
+ if column_exists?(name)
88
+ unless column_exists?(name, column_type, def_options)
89
+ debugger
90
+ change(name, column_def.sql_type, options)
91
+ puts "#{name} has been changed!"
92
+ end
93
+ else
94
+ puts "creating column"
95
+ @base.add_column(@table_name, name, column_def.sql_type, options)
96
+ end
97
+ end
98
+ end
99
+
100
+ def build_column_definition(column_name, column_type, options = {})
101
+ column = ColumnDefinition.new(@base, column_name, column_type)
102
+ if options[:limit]
103
+ column.limit = options[:limit]
104
+ elsif native[column_type.to_sym].is_a?(Hash)
105
+ column.limit = native[column_type.to_sym][:limit]
106
+ end
107
+ column.precision = options[:precision]
108
+ column.scale = options[:scale]
109
+ column.default = options[:default]
110
+ column.null = options[:null]
111
+ column
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ module ActiveRecord
118
+ class Schema
119
+ def self.ensure(options={}, &block)
120
+ self.define(options, &block)
121
+ end
122
+ end
123
+ end
124
+
125
+ module ActiveRecord
126
+ module ConnectionAdapters # :nodoc:
127
+ module SchemaStatements
128
+ def table(table_name, options = {}, &block)
129
+ if table_exists?(table_name)
130
+ puts "table already exists"
131
+ ensure_table(table_name, &block) # what to do about changing table options
132
+ else
133
+ puts "creating table"
134
+ create_table(table_name, options, &block)
135
+ end
136
+ end
137
+
138
+ def ensure_table(table_name)
139
+ yield EnsuredTable.new(table_name, self)
140
+ end
141
+
142
+ def ensure_index(table_name, column_name, options = {})
143
+ begin
144
+ add_index(table_name, column_name, options)
145
+ rescue => e
146
+ if e.message =~ /Duplicate key/
147
+ puts "index already exists"
148
+ else
149
+ raise e
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ensured_schema
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Chris Conley
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-08 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Smarter migrations
23
+ email:
24
+ - chris@chrisconley.me
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - Rakefile
35
+ - ensured_schema.gemspec
36
+ - lib/ensured_schema.rb
37
+ - lib/ensured_schema/version.rb
38
+ has_rdoc: true
39
+ homepage: http://rubygems.org/gems/ensured_schema
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ hash: 3
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project: ensured_schema
68
+ rubygems_version: 1.3.7
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Ensures database schema always matches your schema.rb file
72
+ test_files: []
73
+