datamappify 0.2.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile +4 -0
  6. data/README.md +69 -78
  7. data/Rakefile +20 -13
  8. data/datamappify.gemspec +29 -57
  9. data/lib/datamappify.rb +7 -16
  10. data/lib/datamappify/data.rb +6 -0
  11. data/lib/datamappify/data/association_methods.rb +29 -0
  12. data/lib/datamappify/data/base.rb +11 -0
  13. data/lib/datamappify/entity.rb +44 -0
  14. data/lib/datamappify/entity/associated_collection.rb +28 -0
  15. data/lib/datamappify/entity/associated_entity.rb +28 -0
  16. data/lib/datamappify/entity/association_methods.rb +20 -0
  17. data/lib/datamappify/repository.rb +65 -0
  18. data/lib/datamappify/repository/persistence.rb +38 -0
  19. data/lib/datamappify/version.rb +3 -0
  20. data/spec/entity_spec.rb +83 -0
  21. data/spec/repository/finders_and_persistence_spec.rb +71 -0
  22. data/spec/repository_spec.rb +60 -0
  23. data/spec/spec_helper.rb +24 -0
  24. data/spec/support/active_record_tables.rb +34 -0
  25. data/spec/support/comment.rb +9 -0
  26. data/spec/support/role.rb +9 -0
  27. data/spec/support/user.rb +21 -0
  28. metadata +244 -79
  29. data/MIT-LICENSE +0 -20
  30. data/VERSION +0 -1
  31. data/lib/datamappify/associations.rb +0 -21
  32. data/lib/datamappify/collection.rb +0 -46
  33. data/lib/datamappify/fake/column.rb +0 -17
  34. data/lib/datamappify/fake/connection.rb +0 -77
  35. data/lib/datamappify/fake/index.rb +0 -34
  36. data/lib/datamappify/railtie.rb +0 -10
  37. data/lib/datamappify/resource.rb +0 -35
  38. data/lib/datamappify/schema_dumper.rb +0 -21
  39. data/lib/tasks/datamappify.rake +0 -15
  40. data/vendor/auto_migrations/MIT-LICENSE +0 -20
  41. data/vendor/auto_migrations/README +0 -46
  42. data/vendor/auto_migrations/Rakefile +0 -24
  43. data/vendor/auto_migrations/init.rb +0 -2
  44. data/vendor/auto_migrations/lib/auto_migrations.rb +0 -178
  45. data/vendor/auto_migrations/lib/tasks/auto_migrations_tasks.rake +0 -20
  46. data/vendor/auto_migrations/test/auto_migrations_test.rb +0 -8
@@ -1,17 +0,0 @@
1
- require 'active_record/connection_adapters/abstract/schema_definitions'
2
-
3
- module Datamappify
4
- module Fake
5
- class Column < ActiveRecord::ConnectionAdapters::Column
6
- def initialize(property)
7
- allow_null = property[:options].include?(:null) ? property[:options][:null] : true
8
-
9
- super(property[:name], property[:options][:default], property[:sql_type], allow_null)
10
-
11
- @limit = property[:options][:limit]
12
- @precision = property[:options][:precision]
13
- @scale = property[:options][:scale]
14
- end
15
- end
16
- end
17
- end
@@ -1,77 +0,0 @@
1
- module Datamappify
2
- module Fake
3
- class Connection
4
- def columns(table)
5
- @primary_key = "id"
6
- resource = get_resource(table)
7
- columns = []
8
-
9
- # manually add the primary key property (without the :primary_key option)
10
- # as ActiveRecord ignores the primary_key column
11
- add_primary_key_to(resource) unless is_a_join_table?(table)
12
-
13
- resource[:properties].map do |property|
14
- if (property[:name] == :timestamps)
15
- create_timestamps_for(resource)
16
- else
17
- columns << Column.new(property)
18
- end
19
- end
20
-
21
- columns
22
- end
23
-
24
- def primary_key(table)
25
- resource = get_resource(table)
26
- primary_key_for(resource)
27
- end
28
-
29
- def indexes(table)
30
- resource = get_resource(table)
31
- resource[:indexes].map do |index|
32
- Index.new(resource, index)
33
- end
34
- end
35
-
36
- private
37
-
38
- def get_resource(table)
39
- Collection.get.select do |r|
40
- r[:table_name].to_s == table.to_s
41
- end[0]
42
- end
43
-
44
- def create_timestamps_for(resource)
45
- resource[:properties] << {
46
- :name => :created_at,
47
- :sql_type => :datetime,
48
- :options => {},
49
- }
50
- resource[:properties] << {
51
- :name => :updated_at,
52
- :sql_type => :datetime,
53
- :options => {},
54
- }
55
- end
56
-
57
- def primary_key_for(resource)
58
- resource[:properties].select do |property|
59
- return property[:name].to_s if property[:options][:primary_key]
60
- end
61
- "id"
62
- end
63
-
64
- def add_primary_key_to(resource)
65
- resource[:properties] << {
66
- :name => primary_key_for(resource),
67
- :sql_type => :datetime,
68
- :options => {},
69
- }
70
- end
71
-
72
- def is_a_join_table?(table)
73
- Associations.join_tables.key?(table)
74
- end
75
- end
76
- end
77
- end
@@ -1,34 +0,0 @@
1
- require 'active_record/connection_adapters/abstract/schema_statements'
2
-
3
- module Datamappify
4
- module Fake
5
- class Index
6
- include ActiveRecord::ConnectionAdapters::SchemaStatements
7
-
8
- def initialize(resource, index)
9
- @resource = resource
10
- @index = index
11
- end
12
-
13
- def table
14
- @resource[:table_name]
15
- end
16
-
17
- def name
18
- @index[:options].include?(:name) ? @index[:options][:name].to_s : index_name(table, :column => @index[:columns])
19
- end
20
-
21
- def columns
22
- @index[:columns]
23
- end
24
-
25
- def unique
26
- @index[:options][:unique] if @index[:options].include?(:unique)
27
- end
28
-
29
- def lengths
30
- @index[:options][:length] if @index[:options].include?(:length)
31
- end
32
- end
33
- end
34
- end
@@ -1,10 +0,0 @@
1
- if defined?(Rails::Railtie)
2
- module Datamappify
3
- class Railtie < Rails::Railtie
4
- rake_tasks do
5
- load File.expand_path("../../tasks/datamappify.rake", __FILE__)
6
- load File.expand_path("../../../vendor/auto_migrations/lib/tasks/auto_migrations_tasks.rake", __FILE__)
7
- end
8
- end
9
- end
10
- end
@@ -1,35 +0,0 @@
1
- module Datamappify
2
- module Resource
3
- def self.included(model)
4
- model.send :cattr_accessor, :properties
5
- model.send :cattr_accessor, :indexes
6
-
7
- model.extend Resource::ClassMethods
8
- model.extend Associations::ClassMethods
9
- end
10
-
11
- module ClassMethods
12
- def self.extended(model)
13
- @@model = model
14
-
15
- @@model.properties = []
16
- @@model.indexes = []
17
- end
18
-
19
- def property(name, sql_type=nil, options={})
20
- @@model.properties << {
21
- :name => name,
22
- :sql_type => sql_type,
23
- :options => options,
24
- }
25
- end
26
-
27
- def add_index(columns, options={})
28
- @@model.indexes << {
29
- :columns => columns,
30
- :options => options,
31
- }
32
- end
33
- end
34
- end
35
- end
@@ -1,21 +0,0 @@
1
- module Datamappify
2
- class SchemaDumper < ActiveRecord::SchemaDumper
3
- def self.dump_to_file
4
- File.open(ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb", "w") do |file|
5
- Datamappify::SchemaDumper.dump(ActiveRecord::Base.connection, file)
6
- end
7
- end
8
-
9
- def initialize(connection)
10
- super(connection)
11
- @connection = Datamappify::Fake::Connection.new
12
- end
13
-
14
- def tables(stream)
15
- Datamappify::Collection.get.each do |entry|
16
- tbl = entry[:table_name] or entry[:resource].pluralize
17
- table(tbl, stream)
18
- end
19
- end
20
- end
21
- end
@@ -1,15 +0,0 @@
1
- namespace :db do
2
- namespace :schema do
3
- desc "Update schema.rb with Datamappfiy"
4
- task :update => :environment do
5
- Datamappify::SchemaDumper.dump_to_file
6
- Rake::Task["db:schema:update"].reenable
7
- end
8
-
9
- desc "Auto-migrate via schema.rb"
10
- task :auto_migrate => :environment do
11
- Rake::Task["db:schema:update"].invoke
12
- Rake::Task["db:auto:migrate"].invoke
13
- end
14
- end
15
- end
@@ -1,20 +0,0 @@
1
- Copyright (c) 2007 PJ Hyett
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,46 +0,0 @@
1
- == AutoMigrations
2
-
3
- Forget migrations, auto-migrate!
4
-
5
-
6
- == Usage
7
-
8
- Write out your schema (or use an existing one)
9
-
10
- $ cat db/schema.rb
11
-
12
- ActiveRecord::Schema.define do
13
-
14
- create_table :posts do |t|
15
- t.string :title
16
- t.text :body
17
- t.timestamps
18
- end
19
-
20
- end
21
-
22
- $ rake db:auto:migrate
23
-
24
- Created posts table
25
-
26
- ...a few days later
27
-
28
- $ cat db/schema.rb
29
-
30
- ActiveRecord::Schema.define do
31
-
32
- create_table :posts do |t|
33
- t.string :title
34
- t.text :content
35
- t.timestamps
36
- end
37
-
38
- end
39
-
40
- $ rake db:auto:migrate
41
- -- add_column("posts", :content, :text)
42
- -> 0.0307s
43
- -- remove_column("posts", "body")
44
- -> 0.0311s
45
-
46
- * PJ Hyett [ pjhyett@gmail.com ]
@@ -1,24 +0,0 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rake/rdoctask'
4
-
5
- desc 'Default: run unit tests.'
6
- task :default => :test
7
-
8
- desc 'Test the auto_migrations plugin.'
9
- Rake::TestTask.new(:test) do |t|
10
- t.libs << 'lib'
11
- t.pattern = 'test/**/*_test.rb'
12
- t.verbose = true
13
- end
14
-
15
- desc 'Generate documentation for the auto_migrations plugin.'
16
- Rake::RDocTask.new(:rdoc) do |rdoc|
17
- files = ['README', 'LICENSE', 'lib/**/*.rb']
18
- rdoc.rdoc_files.add(files)
19
- rdoc.main = "README" # page to start on
20
- rdoc.title = "auto_migrations"
21
- rdoc.template = File.exists?(t="/Users/chris/ruby/projects/err/rock/template.rb") ? t : "/var/www/rock/template.rb"
22
- rdoc.rdoc_dir = 'doc' # rdoc output folder
23
- rdoc.options << '--inline-source'
24
- end
@@ -1,2 +0,0 @@
1
- require 'auto_migrations'
2
- ActiveRecord::Migration.send :include, AutoMigrations
@@ -1,178 +0,0 @@
1
- module AutoMigrations
2
-
3
- def self.run
4
- # Turn off schema_info code for auto-migration
5
- class << ActiveRecord::Schema
6
- alias :old_define :define
7
- attr_accessor :version
8
- def define(info={}, &block) @version = Time.now.utc.strftime("%Y%m%d%H%M%S"); instance_eval(&block) end
9
- end
10
-
11
- load(Rails.root.join('db', 'schema.rb'))
12
- ActiveRecord::Migration.drop_unused_tables
13
- ActiveRecord::Migration.drop_unused_indexes
14
- ActiveRecord::Migration.update_schema_version(ActiveRecord::Schema.version) if ActiveRecord::Schema.version
15
-
16
- class << ActiveRecord::Schema
17
- alias :define :old_define
18
- end
19
- end
20
-
21
- def self.schema_to_migration(with_reset = false)
22
- schema_in = File.read(Rails.root.join("db", "schema.rb"))
23
- schema_in.gsub!(/#(.)+\n/, '')
24
- schema_in.sub!(/ActiveRecord::Schema.define(.+)do[ ]?\n/, '')
25
- schema_in.gsub!(/^/, ' ')
26
- schema = "class InitialSchema < ActiveRecord::Migration\n def self.up\n"
27
- schema += " # We're resetting the migrations database...\n" +
28
- " drop_table :schema_migrations\n" +
29
- " initialize_schema_migrations_table\n\n" if with_reset
30
- schema += schema_in
31
- schema << "\n def self.down\n"
32
- schema << (ActiveRecord::Base.connection.tables - %w(schema_info schema_migrations)).map do |table|
33
- " drop_table :#{table}\n"
34
- end.join
35
- schema << " end\nend\n"
36
- migration_file = Rails.root.join("db", "migrate", "001_initial_schema.rb")
37
- File.open(migration_file, "w") { |f| f << schema }
38
- puts "Migration created at db/migrate/001_initial_schema.rb"
39
- end
40
-
41
- def self.included(base)
42
- base.extend ClassMethods
43
- class << base
44
- cattr_accessor :tables_in_schema, :indexes_in_schema
45
- self.tables_in_schema, self.indexes_in_schema = [], []
46
- alias_method_chain :method_missing, :auto_migration
47
- end
48
- end
49
-
50
- module ClassMethods
51
-
52
- def method_missing_with_auto_migration(method, *args, &block)
53
- case method
54
- when :create_table
55
- auto_create_table(method, *args, &block)
56
- when :add_index
57
- auto_add_index(method, *args, &block)
58
- else
59
- method_missing_without_auto_migration(method, *args, &block)
60
- end
61
- end
62
-
63
- def auto_create_table(method, *args, &block)
64
- table_name = args.shift.to_s
65
- options = args.pop || {}
66
-
67
- (self.tables_in_schema ||= []) << table_name
68
-
69
- # Table doesn't exist, create it
70
- unless ActiveRecord::Base.connection.tables.include?(table_name)
71
- return method_missing_without_auto_migration(method, *[table_name, options], &block)
72
- end
73
-
74
- # Grab database columns
75
- fields_in_db = ActiveRecord::Base.connection.columns(table_name).inject({}) do |hash, column|
76
- hash[column.name] = column
77
- hash
78
- end
79
-
80
- # Grab schema columns (lifted from active_record/connection_adapters/abstract/schema_statements.rb)
81
- table_definition = ActiveRecord::ConnectionAdapters::TableDefinition.new(ActiveRecord::Base.connection)
82
- primary_key = options[:primary_key] || "id"
83
- table_definition.primary_key(primary_key) unless options[:id] == false
84
- yield table_definition
85
- fields_in_schema = table_definition.columns.inject({}) do |hash, column|
86
- hash[column.name.to_s] = column
87
- hash
88
- end
89
-
90
- # Add fields to db new to schema
91
- (fields_in_schema.keys - fields_in_db.keys).each do |field|
92
- column = fields_in_schema[field]
93
- options = {:limit => column.limit, :precision => column.precision, :scale => column.scale}
94
- options[:default] = column.default.to_s if !column.default.nil?
95
- options[:null] = column.null if !column.null.nil?
96
- add_column table_name, column.name, column.type.to_sym, options
97
- end
98
-
99
- # Remove fields from db no longer in schema
100
- (fields_in_db.keys - fields_in_schema.keys & fields_in_db.keys).each do |field|
101
- column = fields_in_db[field]
102
- remove_column table_name, column.name
103
- end
104
-
105
- (fields_in_schema.keys & fields_in_db.keys).each do |field|
106
- if field != primary_key #ActiveRecord::Base.get_primary_key(table_name)
107
- changed = false # flag
108
- new_type = fields_in_schema[field].type.to_sym
109
- new_attr = {}
110
-
111
- # First, check if the field type changed
112
- if fields_in_schema[field].type.to_sym != fields_in_db[field].type.to_sym
113
- changed = true
114
- end
115
-
116
- # Special catch for precision/scale, since *both* must be specified together
117
- # Always include them in the attr struct, but they'll only get applied if changed = true
118
- new_attr[:precision] = fields_in_schema[field][:precision]
119
- new_attr[:scale] = fields_in_schema[field][:scale]
120
-
121
- # Next, iterate through our extended attributes, looking for any differences
122
- # This catches stuff like :null, :precision, etc
123
- fields_in_schema[field].each_pair do |att,value|
124
- next if att == :type or att == :base or att == :name # special cases
125
- if !value.nil? && value != fields_in_db[field].send(att)
126
- new_attr[att] = value
127
- changed = true
128
- end
129
- end
130
-
131
- # Change the column if applicable
132
- change_column table_name, field, new_type, new_attr if changed
133
- end
134
- end
135
- end
136
-
137
- def auto_add_index(method, *args, &block)
138
- table_name = args.shift.to_s
139
- fields = Array(args.shift).map(&:to_s)
140
- options = args.shift
141
-
142
- index_name = options[:name] if options
143
- index_name ||= ActiveRecord::Base.connection.index_name(table_name, :column => fields)
144
-
145
- (self.indexes_in_schema ||= []) << index_name
146
-
147
- unless ActiveRecord::Base.connection.indexes(table_name).detect { |i| i.name == index_name }
148
- method_missing_without_auto_migration(method, *[table_name, fields, options], &block)
149
- end
150
- end
151
-
152
- def drop_unused_tables
153
- (ActiveRecord::Base.connection.tables - tables_in_schema - %w(schema_info schema_migrations)).each do |table|
154
- drop_table table
155
- end
156
- end
157
-
158
- def drop_unused_indexes
159
- tables_in_schema.each do |table_name|
160
- indexes_in_db = ActiveRecord::Base.connection.indexes(table_name).map(&:name)
161
- (indexes_in_db - indexes_in_schema & indexes_in_db).each do |index_name|
162
- remove_index table_name, :name => index_name
163
- end
164
- end
165
- end
166
-
167
- def update_schema_version(version)
168
- ActiveRecord::Base.connection.update("INSERT INTO schema_migrations VALUES ('#{version}')")
169
-
170
- schema_file = Rails.root.join("db", "schema.rb")
171
- schema = File.read(schema_file)
172
- schema.sub!(/:version => \d+/, ":version => #{version}")
173
- File.open(schema_file, "w") { |f| f << schema }
174
- end
175
-
176
- end
177
-
178
- end