molo 0.6.0 → 0.7.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 (61) hide show
  1. data/Molo.gemspec +56 -2
  2. data/README.markdown +31 -7
  3. data/Rakefile +1 -1
  4. data/VERSION +1 -1
  5. data/lib/tasks/molo.rb +9 -3
  6. data/vendor/rails_sql_views/.gitignore +3 -0
  7. data/vendor/rails_sql_views/CHANGELOG +22 -0
  8. data/vendor/rails_sql_views/CONTRIB +8 -0
  9. data/vendor/rails_sql_views/LICENSE +7 -0
  10. data/vendor/rails_sql_views/README +51 -0
  11. data/vendor/rails_sql_views/Rakefile +74 -0
  12. data/vendor/rails_sql_views/TODO +2 -0
  13. data/vendor/rails_sql_views/VERSION +1 -0
  14. data/vendor/rails_sql_views/init.rb +1 -0
  15. data/vendor/rails_sql_views/lib/active_record/view.rb +76 -0
  16. data/vendor/rails_sql_views/lib/core_ext/module.rb +13 -0
  17. data/vendor/rails_sql_views/lib/rails_sql_views.rb +47 -0
  18. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/abstract/schema_definitions.rb +63 -0
  19. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/abstract/schema_statements.rb +79 -0
  20. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/abstract_adapter.rb +41 -0
  21. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/mysql2_adapter.rb +62 -0
  22. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/mysql_adapter.rb +62 -0
  23. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/oci_adapter.rb +33 -0
  24. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/oracle_adapter.rb +33 -0
  25. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/oracleenhanced_adapter.rb +39 -0
  26. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/oracleenhanced_adapter.rb.orig +72 -0
  27. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/postgresql_adapter.rb +65 -0
  28. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/postgresql_adapter.rb.orig +69 -0
  29. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/sqlite_adapter.rb +66 -0
  30. data/vendor/rails_sql_views/lib/rails_sql_views/connection_adapters/sqlserver_adapter.rb +43 -0
  31. data/vendor/rails_sql_views/lib/rails_sql_views/loader.rb +18 -0
  32. data/vendor/rails_sql_views/lib/rails_sql_views/schema_dumper.rb +112 -0
  33. data/vendor/rails_sql_views/lib/rails_sql_views/version.rb +9 -0
  34. data/vendor/rails_sql_views/rails/init.rb +1 -0
  35. data/vendor/rails_sql_views/rails_sql_views.gemspec +81 -0
  36. data/vendor/rails_sql_views/test/.gitignore +1 -0
  37. data/vendor/rails_sql_views/test/README +63 -0
  38. data/vendor/rails_sql_views/test/adapter_test.rb +82 -0
  39. data/vendor/rails_sql_views/test/connection.example.yml +12 -0
  40. data/vendor/rails_sql_views/test/connection/native_mysql/connection.rb +32 -0
  41. data/vendor/rails_sql_views/test/connection/native_mysql/schema.sql +33 -0
  42. data/vendor/rails_sql_views/test/connection/native_postgresql/connection.rb +31 -0
  43. data/vendor/rails_sql_views/test/connection/native_postgresql/schema.sql +33 -0
  44. data/vendor/rails_sql_views/test/connection/oracle_enhanced/connection.rb +29 -0
  45. data/vendor/rails_sql_views/test/connection/oracle_enhanced/procedures.sql +15 -0
  46. data/vendor/rails_sql_views/test/connection/oracle_enhanced/schema.sql +39 -0
  47. data/vendor/rails_sql_views/test/models/item.rb +4 -0
  48. data/vendor/rails_sql_views/test/models/person.rb +5 -0
  49. data/vendor/rails_sql_views/test/models/person2.rb +3 -0
  50. data/vendor/rails_sql_views/test/models/place.rb +2 -0
  51. data/vendor/rails_sql_views/test/models/v_person.rb +4 -0
  52. data/vendor/rails_sql_views/test/models/v_profile.rb +3 -0
  53. data/vendor/rails_sql_views/test/schema.native_mysql.expected.rb +51 -0
  54. data/vendor/rails_sql_views/test/schema.native_postgresql.expected.rb +51 -0
  55. data/vendor/rails_sql_views/test/schema.oracle_enhanced.expected.rb +51 -0
  56. data/vendor/rails_sql_views/test/schema_dumper_test.rb +117 -0
  57. data/vendor/rails_sql_views/test/test_helper.rb +30 -0
  58. data/vendor/rails_sql_views/test/view_model_test.rb +63 -0
  59. data/vendor/rails_sql_views/test/view_operations_test.rb +36 -0
  60. data/vendor/yaml_db/lib/serialization_helper.rb +15 -10
  61. metadata +58 -4
@@ -0,0 +1,4 @@
1
+ class Item < ActiveRecord::Base
2
+ belongs_to :person
3
+ has_and_belongs_to_many :people
4
+ end
@@ -0,0 +1,5 @@
1
+ class Person < ActiveRecord::Base
2
+ belongs_to :address, :class_name => 'Place', :foreign_key => :address_id
3
+ has_many :owned_items, :class_name => 'Item'
4
+ has_and_belongs_to_many :shared_items, :class_name => 'Item'
5
+ end
@@ -0,0 +1,3 @@
1
+ class Person2 < ActiveRecord::Base
2
+ set_table_name :people2
3
+ end
@@ -0,0 +1,2 @@
1
+ class Place < ActiveRecord::Base
2
+ end
@@ -0,0 +1,4 @@
1
+ require 'active_record/view'
2
+
3
+ class VPerson < ActiveRecord::View
4
+ end
@@ -0,0 +1,3 @@
1
+ class VProfile < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,51 @@
1
+ # This file is auto-generated from the current state of the database. Instead of editing this file,
2
+ # please use the migrations feature of Active Record to incrementally modify your database, and
3
+ # then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6
+ # to create the application database on another system, you should be using db:schema:load, not running
7
+ # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
9
+ #
10
+ # It's strongly recommended to check this file into your version control system.
11
+
12
+ ActiveRecord::Schema.define(:version => 0) do
13
+
14
+ create_table "items", :force => true do |t|
15
+ t.integer "person_id"
16
+ end
17
+
18
+ create_table "items_people", :id => false, :force => true do |t|
19
+ t.integer "person_id"
20
+ t.integer "item_id"
21
+ end
22
+
23
+ create_table "people", :force => true do |t|
24
+ t.string "first_name"
25
+ t.string "last_name"
26
+ t.string "ssn", :limit => 64
27
+ t.integer "address_id"
28
+ end
29
+
30
+ create_table "people2", :force => true do |t|
31
+ t.string "first_name"
32
+ t.string "last_name"
33
+ t.string "ssn", :limit => 64
34
+ end
35
+
36
+ create_table "places", :force => true do |t|
37
+ t.text "address"
38
+ t.string "city"
39
+ t.string "cstate"
40
+ t.string "country", :limit => 2
41
+ end
42
+
43
+ create_view "v_people", "select `people`.`id` AS `id`,`people`.`first_name` AS `f_name`,`people`.`last_name` AS `l_name`,`people`.`ssn` AS `social_security`,`people`.`address_id` AS `address_id` from `people`", :force => true do |v|
44
+ v.column :id
45
+ v.column :f_name
46
+ v.column :l_name
47
+ v.column :social_security
48
+ v.column :address_id
49
+ end
50
+
51
+ end
@@ -0,0 +1,51 @@
1
+ # This file is auto-generated from the current state of the database. Instead of editing this file,
2
+ # please use the migrations feature of Active Record to incrementally modify your database, and
3
+ # then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6
+ # to create the application database on another system, you should be using db:schema:load, not running
7
+ # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
9
+ #
10
+ # It's strongly recommended to check this file into your version control system.
11
+
12
+ ActiveRecord::Schema.define(:version => 0) do
13
+
14
+ create_table "items", :force => true do |t|
15
+ t.integer "person_id"
16
+ end
17
+
18
+ create_table "items_people", :id => false, :force => true do |t|
19
+ t.integer "person_id"
20
+ t.integer "item_id"
21
+ end
22
+
23
+ create_table "people", :force => true do |t|
24
+ t.string "first_name"
25
+ t.string "last_name"
26
+ t.string "ssn", :limit => 64
27
+ t.integer "address_id"
28
+ end
29
+
30
+ create_table "people2", :force => true do |t|
31
+ t.string "first_name"
32
+ t.string "last_name"
33
+ t.string "ssn", :limit => 64
34
+ end
35
+
36
+ create_table "places", :force => true do |t|
37
+ t.text "address"
38
+ t.string "city"
39
+ t.string "cstate"
40
+ t.string "country", :limit => 2
41
+ end
42
+
43
+ create_view "v_people", "SELECT people.id, people.first_name AS f_name, people.last_name AS l_name, people.ssn AS social_security, people.address_id FROM people;", :force => true do |v|
44
+ v.column :id
45
+ v.column :f_name
46
+ v.column :l_name
47
+ v.column :social_security
48
+ v.column :address_id
49
+ end
50
+
51
+ end
@@ -0,0 +1,51 @@
1
+ # This file is auto-generated from the current state of the database. Instead of editing this file,
2
+ # please use the migrations feature of Active Record to incrementally modify your database, and
3
+ # then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6
+ # to create the application database on another system, you should be using db:schema:load, not running
7
+ # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
9
+ #
10
+ # It's strongly recommended to check this file into your version control system.
11
+
12
+ ActiveRecord::Schema.define(:version => 0) do
13
+
14
+ create_table "items", :force => true do |t|
15
+ t.integer "person_id", :precision => 38, :scale => 0
16
+ end
17
+
18
+ create_table "items_people", :id => false, :force => true do |t|
19
+ t.integer "person_id", :precision => 38, :scale => 0
20
+ t.integer "item_id", :precision => 38, :scale => 0
21
+ end
22
+
23
+ create_table "people", :force => true do |t|
24
+ t.string "first_name"
25
+ t.string "last_name"
26
+ t.string "ssn", :limit => 64
27
+ t.integer "address_id", :precision => 38, :scale => 0
28
+ end
29
+
30
+ create_table "people2", :force => true do |t|
31
+ t.string "first_name"
32
+ t.string "last_name"
33
+ t.string "ssn", :limit => 64
34
+ end
35
+
36
+ create_table "places", :force => true do |t|
37
+ t.string "address", :limit => 2000
38
+ t.string "city"
39
+ t.string "cstate"
40
+ t.string "country", :limit => 2
41
+ end
42
+
43
+ create_view "v_people", "select id, first_name, last_name, ssn, address_id from people", :force => true do |v|
44
+ v.column :id
45
+ v.column :f_name
46
+ v.column :l_name
47
+ v.column :social_security
48
+ v.column :address_id
49
+ end
50
+
51
+ end
@@ -0,0 +1,117 @@
1
+ require "#{File.dirname(__FILE__)}/test_helper"
2
+ require 'active_record/schema_dumper'
3
+
4
+ class SchemaDumperTest < Test::Unit::TestCase
5
+ def setup
6
+ teardown
7
+ end
8
+ def teardown
9
+ ['V_PEOPLE', 'V_PROFILE'].each do |view|
10
+ if ActiveRecord::Base.connection.adapter_name == 'OracleEnhanced'
11
+ ActiveRecord::Base.connection.execute("
12
+ DECLARE
13
+ CURSOR C1 is SELECT view_name FROM user_views where view_name = '#{view}';
14
+ BEGIN
15
+ FOR I IN C1 LOOP
16
+ EXECUTE IMMEDIATE 'DROP VIEW '||I.view_name||'';
17
+ END LOOP;
18
+ END;
19
+ ");
20
+ else
21
+ ActiveRecord::Base.connection.execute("drop view if exists #{view}")
22
+ end
23
+ end
24
+ end
25
+ def test_view
26
+ create_people_view
27
+ stream = StringIO.new
28
+ dumper = ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
29
+ stream.rewind
30
+ assert_equal File.open(File.dirname(__FILE__) + "/schema.#{$connection}.expected.rb", 'r').readlines, stream.readlines
31
+ end
32
+ def test_dump_and_load
33
+ create_people_view
34
+ assert_dump_and_load_succeed
35
+ end
36
+ def test_union
37
+ Person.create(:first_name => 'Joe', :last_name => 'User', :ssn => '123456789')
38
+ Person2.create(:first_name => 'Jane', :last_name => 'Doe', :ssn => '222334444')
39
+
40
+ select_stmt = <<-HERE
41
+ select first_name, last_name, ssn from people
42
+ UNION
43
+ select first_name, last_name, ssn from people2
44
+ HERE
45
+
46
+ ActiveRecord::Base.connection.create_view(:v_profile, select_stmt, :force => true) do |v|
47
+ v.column :first_name
48
+ v.column :last_name
49
+ v.column :ssn
50
+ end
51
+
52
+ assert_dump_and_load_succeed
53
+ end
54
+ def test_view_creation_order
55
+ ActiveRecord::SchemaDumper.view_creation_order << :v_people
56
+ create_people_view
57
+ assert_dump_and_load_succeed
58
+ ActiveRecord::SchemaDumper.view_creation_order.pop
59
+ end
60
+ def test_symbol_ignore
61
+ ActiveRecord::SchemaDumper.ignore_views << :v_people
62
+ create_people_view
63
+ assert_dump_and_load_succeed
64
+ ActiveRecord::SchemaDumper.ignore_views.pop
65
+ end
66
+ def test_regex_ignore
67
+ ActiveRecord::SchemaDumper.ignore_views << Regexp.new(/v_people/)
68
+ create_people_view
69
+ assert_dump_and_load_succeed
70
+ ActiveRecord::SchemaDumper.ignore_views.pop
71
+ end
72
+ def test_non_allowed_object_raises_error
73
+ create_people_view
74
+ ActiveRecord::SchemaDumper.ignore_views << 0
75
+ begin
76
+ schema_file = File.dirname(__FILE__) + "/schema.#{$connection}.out.rb"
77
+ File.open(schema_file, "w") do |file|
78
+ assert_raise(StandardError) do
79
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
80
+ end
81
+ end
82
+ ensure
83
+ ActiveRecord::SchemaDumper.ignore_views.pop
84
+ end
85
+ end
86
+
87
+ def test_logging_error
88
+ ActiveRecord::SchemaDumper.ignore_views << 0
89
+ old_logger = ActiveRecord::Base.logger
90
+
91
+ begin
92
+ mock_logger = flexmock('logger', :error => nil)
93
+ mock_logger.should_receive(:error)
94
+ ActiveRecord::Base.logger = mock_logger
95
+ schema_file = File.dirname(__FILE__) + "/schema.#{$connection}.out.rb"
96
+ File.open(schema_file, "w") do |file|
97
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
98
+ end
99
+ ensure
100
+ ActiveRecord::SchemaDumper.ignore_views.pop
101
+ ActiveRecord::Base.logger = old_logger
102
+ end
103
+ end
104
+
105
+ def assert_dump_and_load_succeed
106
+ schema_file = File.dirname(__FILE__) + "/schema.#{$connection}.out.rb"
107
+ assert_nothing_raised do
108
+ File.open(schema_file, "w") do |file|
109
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
110
+ end
111
+ end
112
+
113
+ assert_nothing_raised do
114
+ load(schema_file)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,30 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ $:.unshift(File.dirname(__FILE__))
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'pp'
7
+ require 'flexmock/test_unit'
8
+
9
+ require 'active_record'
10
+ #$connection = (ENV['DB'] || 'native_mysql')
11
+ $connection = (ENV['DB'] || 'native_postgresql')
12
+ require "connection/#{$connection}/connection"
13
+ require 'rails_sql_views'
14
+
15
+ require 'models/person'
16
+ require 'models/person2'
17
+ require 'models/v_person'
18
+
19
+ class Test::Unit::TestCase
20
+ def create_people_view
21
+ ActiveRecord::Base.connection.create_view(:v_people,
22
+ 'select id, first_name, last_name, ssn, address_id from people', :force => true) do |v|
23
+ v.column :id
24
+ v.column :f_name
25
+ v.column :l_name
26
+ v.column :social_security
27
+ v.column :address_id
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,63 @@
1
+ require "#{File.dirname(__FILE__)}/test_helper"
2
+
3
+ require 'models/item'
4
+ require 'models/place'
5
+
6
+ class ViewModelTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ create_people_view
10
+ VPerson.send(:based_on, Person)
11
+
12
+ @address = Place.create!
13
+ @person = Person.create!(:first_name => 'Primus', :address => @address)
14
+ @items = [ @person.owned_items.create!, @person.owned_items.create! ]
15
+ @sharable_items = [ Item.create!, Item.create!, Item.create! ]
16
+ @person.shared_items << @sharable_items[0]
17
+ @person.shared_items << @sharable_items[2]
18
+
19
+ @vperson = VPerson.find(@person.id)
20
+ end
21
+
22
+ def cleanup
23
+ Item.delete_all
24
+ Person.delete_all
25
+ Place.delete_all
26
+ end
27
+
28
+ def test_same_person
29
+ assert_equal @person.id, @vperson.id
30
+ end
31
+
32
+ def test_cloned_belongs_to_association_exists
33
+ reflection = VPerson.reflect_on_association(:address)
34
+ assert_not_nil reflection
35
+ end
36
+
37
+ def test_access_cloned_belongs_to_association
38
+ assert_equal @address, @vperson.address
39
+ end
40
+
41
+ def test_cloned_has_many_association_exists
42
+ reflection = VPerson.reflect_on_association(:owned_items)
43
+ assert_not_nil reflection
44
+ end
45
+
46
+ def test_access_cloned_has_many_association
47
+ items = @vperson.owned_items
48
+ assert_equal 2, items.size
49
+ assert_equal @items.sort_by(&:id), items.sort_by(&:id)
50
+ end
51
+
52
+ def test_cloned_habtm_association_exists
53
+ reflection = VPerson.reflect_on_association(:shared_items)
54
+ assert_not_nil reflection
55
+ end
56
+
57
+ def test_access_cloned_habtm_association
58
+ items = @vperson.shared_items
59
+ assert_equal 2, items.size
60
+ expected_items = [ @sharable_items[0], @sharable_items[2] ]
61
+ assert_equal expected_items.sort_by(&:id), items.sort_by(&:id)
62
+ end
63
+ end
@@ -0,0 +1,36 @@
1
+ require "#{File.dirname(__FILE__)}/test_helper"
2
+
3
+ class ViewOperationsTest < Test::Unit::TestCase
4
+ def test_create_view
5
+ Person.create(:first_name => 'John', :last_name => 'Doe', :ssn => '123456789')
6
+ assert_nothing_raised do
7
+ ActiveRecord::Base.connection.create_view(:v_people,
8
+ 'select first_name, last_name, ssn from people', :force => true) do |v|
9
+ v.column :f_name
10
+ v.column :l_name
11
+ v.column :social_security
12
+ end
13
+ end
14
+ p = Person.find(:first)
15
+ vp = VPerson.find(:first)
16
+ assert_equal p.first_name, vp.f_name
17
+ end
18
+ def test_drop_view
19
+ assert_nothing_raised do
20
+ ActiveRecord::Base.connection.create_view(:v_place,
21
+ 'select address, city, cstate, country from places', :force => true) do |v|
22
+ v.column :v_address
23
+ v.column :v_city
24
+ v.column :v_state
25
+ v.column :v_country
26
+ end
27
+ ActiveRecord::Base.connection.drop_view(:v_place)
28
+ end
29
+ assert_raises(ActiveRecord::StatementInvalid) do
30
+ ActiveRecord::Base.connection.execute "SELECT * FROM v_place"
31
+ end
32
+ end
33
+ def test_no_view_raises_error
34
+ assert_raises(RuntimeError) { ActiveRecord::Base.connection.view_select_statement('foo') }
35
+ end
36
+ end
@@ -9,16 +9,20 @@ module SerializationHelper
9
9
  @extension = helper.extension
10
10
  end
11
11
 
12
- def dump(filename)
12
+ def dump(filename, *opts)
13
13
  disable_logger
14
- @dumper.dump(File.new(filename, "w"))
14
+ @dumper.dump(File.new(filename, "w"), *opts)
15
15
  reenable_logger
16
16
  end
17
17
 
18
- def dump_to_dir(dirname)
18
+ def dump_to_dir(dirname, *opts)
19
+ options = opts.extract_options!
19
20
  Dir.mkdir(dirname)
20
21
  tables = @dumper.tables
21
22
  tables.each do |table|
23
+ next if options[:except].include? table
24
+ next if !options[:only].include? table
25
+
22
26
  io = File.new "#{dirname}/#{table}.#{@extension}", "w"
23
27
  @dumper.before_table(io, table)
24
28
  @dumper.dump_table io, table
@@ -34,9 +38,7 @@ module SerializationHelper
34
38
 
35
39
  def load_from_dir(dirname, truncate = true)
36
40
  Dir.entries(dirname).each do |filename|
37
- if filename =~ /^[.]/
38
- next
39
- end
41
+ next if filename =~ /^[.]/
40
42
  @loader.load(File.new("#{dirname}/#{filename}", "r"), truncate)
41
43
  end
42
44
  end
@@ -68,9 +70,7 @@ module SerializationHelper
68
70
 
69
71
  def self.load_table(table, data, truncate = true)
70
72
  column_names = data['columns']
71
- if truncate
72
- truncate_table(table)
73
- end
73
+ truncate_table(table) if truncate
74
74
  load_records(table, column_names, data['records'])
75
75
  reset_pk_sequence!(table)
76
76
  end
@@ -141,8 +141,13 @@ module SerializationHelper
141
141
 
142
142
  end
143
143
 
144
- def self.dump(io)
144
+ def self.dump(io, *opts)
145
+ options = opts.extract_options!
146
+
145
147
  tables.each do |table|
148
+ next if options[:except].include? table
149
+ next if !options[:only].include? table
150
+
146
151
  before_table(io, table)
147
152
  dump_table(io, table)
148
153
  after_table(io, table)