datamappify 0.2.2 → 0.9.0

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.
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