xbar 0.0.1 → 0.4.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 (80) hide show
  1. data/Appraisals +25 -0
  2. data/README.mkdn +215 -0
  3. data/Rakefile +337 -1
  4. data/examples/README +5 -0
  5. data/examples/config/simple.json +22 -0
  6. data/examples/example1.rb +34 -0
  7. data/examples/migrations/1_create_users.rb +10 -0
  8. data/examples/setup.rb +43 -0
  9. data/gemfiles/rails3.gemfile +8 -0
  10. data/gemfiles/rails3.gemfile.lock +74 -0
  11. data/gemfiles/rails31.gemfile +8 -0
  12. data/gemfiles/rails31.gemfile.lock +83 -0
  13. data/gemfiles/rails32.gemfile +7 -0
  14. data/gemfiles/rails32.gemfile.lock +117 -0
  15. data/gemfiles/rails4.gemfile +9 -0
  16. data/gemfiles/rails4.gemfile.lock +134 -0
  17. data/lib/migrations/1_create_usage_statistics.rb +23 -0
  18. data/lib/xbar/association.rb +49 -0
  19. data/lib/xbar/association_collection.rb +69 -0
  20. data/lib/xbar/colors.rb +32 -0
  21. data/lib/xbar/has_and_belongs_to_many_association.rb +17 -0
  22. data/lib/xbar/logger.rb +14 -0
  23. data/lib/xbar/mapper.rb +304 -0
  24. data/lib/xbar/migration.rb +76 -0
  25. data/lib/xbar/model.rb +165 -0
  26. data/lib/xbar/proxy.rb +249 -0
  27. data/lib/xbar/rails2/association.rb +133 -0
  28. data/lib/xbar/rails2/persistence.rb +39 -0
  29. data/lib/xbar/rails3/arel.rb +13 -0
  30. data/lib/xbar/rails3/association.rb +112 -0
  31. data/lib/xbar/rails3/persistence.rb +37 -0
  32. data/lib/xbar/rails3.1/singular_association.rb +34 -0
  33. data/lib/xbar/scope_proxy.rb +55 -0
  34. data/lib/xbar/shard.rb +95 -0
  35. data/lib/xbar/version.rb +2 -2
  36. data/lib/xbar.rb +121 -2
  37. data/run +27 -0
  38. data/spec/config/acme.json +53 -0
  39. data/spec/config/connection.rb +2 -0
  40. data/spec/config/default.json +160 -0
  41. data/spec/config/duplicate_shard.json +21 -0
  42. data/spec/config/missing_key.json +20 -0
  43. data/spec/config/new_shards.json +29 -0
  44. data/spec/config/no_master_shard.json +19 -0
  45. data/spec/config/not_entire_sharded.json +23 -0
  46. data/spec/config/octopus.json +27 -0
  47. data/spec/config/octopus_rails.json +25 -0
  48. data/spec/config/production_fully_replicated.json +21 -0
  49. data/spec/config/production_raise_error.json +17 -0
  50. data/spec/config/simple.json +22 -0
  51. data/spec/config/single_adapter.json +20 -0
  52. data/spec/console.rb +15 -0
  53. data/spec/migrations/10_create_users_using_replication.rb +12 -0
  54. data/spec/migrations/11_add_field_in_all_slaves.rb +11 -0
  55. data/spec/migrations/12_create_users_using_block.rb +23 -0
  56. data/spec/migrations/13_create_users_using_block_and_using.rb +15 -0
  57. data/spec/migrations/1_create_users_on_master.rb +9 -0
  58. data/spec/migrations/2_create_users_on_canada.rb +11 -0
  59. data/spec/migrations/3_create_users_on_both_shards.rb +11 -0
  60. data/spec/migrations/4_create_users_on_shards_of_a_group.rb +11 -0
  61. data/spec/migrations/5_create_users_on_multiples_groups.rb +11 -0
  62. data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +11 -0
  63. data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +11 -0
  64. data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +11 -0
  65. data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +11 -0
  66. data/spec/spec_helper.rb +25 -0
  67. data/spec/support/database_models.rb +78 -0
  68. data/spec/support/xbar_helper.rb +42 -0
  69. data/spec/xbar/association_spec.rb +660 -0
  70. data/spec/xbar/controller_spec.rb +40 -0
  71. data/spec/xbar/logger_spec.rb +22 -0
  72. data/spec/xbar/mapper_spec.rb +283 -0
  73. data/spec/xbar/migration_spec.rb +110 -0
  74. data/spec/xbar/model_spec.rb +434 -0
  75. data/spec/xbar/proxy_spec.rb +124 -0
  76. data/spec/xbar/replication_spec.rb +94 -0
  77. data/spec/xbar/scope_proxy_spec.rb +22 -0
  78. data/spec/xbar/shard_spec.rb +36 -0
  79. data/xbar.gemspec +13 -3
  80. metadata +231 -10
@@ -0,0 +1,17 @@
1
+ {
2
+ "__COMMENT": "Production Raise Error",
3
+
4
+ "connections": {
5
+ "duplicated_shard_name": {"database": "xbar_shard5", "adapter": "mysql2", "host": "localhost"},
6
+ "duplicated_shard_name": {"database": "xbar_shard4", "adapter": "mysql2", "host": "localhost"}
7
+ },
8
+
9
+ "environments": {
10
+ "shards": {
11
+ "shards": {
12
+ "history_shard": "duplicated_shard_name",
13
+ "country_shard": "duplicated_shard_name"
14
+ }
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "__COMMENT": "Simple SQLite French Environment",
3
+
4
+ "connections": {
5
+ "paris_m": { "adapter": "sqlite3", "database": "/tmp/paris.sqlite3"},
6
+ "france_1": { "adapter": "sqlite3", "database": "/tmp/france_1.sqlite3"},
7
+ "france_2": { "adapter": "sqlite3", "database": "/tmp/france_2.sqlite3"},
8
+ "france_3": { "adapter": "sqlite3", "database": "/tmp/france_3.sqlite3"}
9
+ },
10
+
11
+ "environments": {
12
+ "test": {
13
+ "shards": {
14
+ "master": "paris_m",
15
+ "france": ["france_1", "france_2", "france_3"],
16
+ "france_nord": "france_1",
17
+ "france_central": "france_2",
18
+ "france_sud": "france_3"
19
+ }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "__COMMENT": "Acme Corporation Environments with a single adapter used in test environment",
3
+ "__COMMENT": "Although four connections are defined, only two adapters will be installed",
4
+
5
+ "connections": {
6
+ "mysql_m": "mysql2://root@localhost:3306/master",
7
+ "inventory_1": "postgres://postgres@127.0.0.1/russia_1",
8
+ "inventory_2": "postgres://postgres@127.0.0.1/russia_2",
9
+ "sales_1": "mysql2://root:graceling@deimos.thirdmode.com:3307/canada"
10
+ },
11
+
12
+ "environments": {
13
+ "test": {
14
+ "shards": {
15
+ "master": "inventory_1",
16
+ "sales": "inventory_2"
17
+ }
18
+ }
19
+ }
20
+ }
data/spec/console.rb ADDED
@@ -0,0 +1,15 @@
1
+ # From XBar root directory,
2
+ # irb -I spec
3
+ # require 'console'
4
+
5
+ require 'rspec'
6
+ require 'spec_helper'
7
+ require 'support/database_models'
8
+
9
+ module XBar
10
+ def self.directory
11
+ File.expand_path(File.dirname(__FILE__))
12
+ end
13
+ end
14
+
15
+ # XBar::Mapper.reset
@@ -0,0 +1,12 @@
1
+ class CreateUsersUsingReplication < ActiveRecord::Migration
2
+ using :china
3
+
4
+ def self.up
5
+ Cat.create!(:name => "Replication")
6
+ end
7
+
8
+ def self.down
9
+ Cat.delete_all
10
+ end
11
+
12
+ end
@@ -0,0 +1,11 @@
1
+ class AddFieldInAllSlaves < ActiveRecord::Migration
2
+ using(:slave1, :slave2, :slave3, :slave4)
3
+
4
+ def self.up
5
+ Cat.create!(:name => "Slaves")
6
+ end
7
+
8
+ def self.down
9
+ Cat.delete_all
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ class CreateUsersUsingBlock < ActiveRecord::Migration
2
+ def self.up
3
+ XBar.using(:brazil) do
4
+ User.create!(:name => "UsingBlock1")
5
+ User.create!(:name => "UsingBlock2")
6
+ end
7
+
8
+ XBar.using(:canada) do
9
+ User.create!(:name => "UsingCanada")
10
+ User.create!(:name => "UsingCanada2")
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ XBar.using(:brazil) do
16
+ User.delete_all
17
+ end
18
+
19
+ XBar.using(:canada) do
20
+ User.delete_all
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ class CreateUsersUsingBlockAndUsing < ActiveRecord::Migration
2
+ using(:brazil)
3
+
4
+ def self.up
5
+ XBar.using(:canada) do
6
+ User.create!(:name => "Canada")
7
+ end
8
+
9
+ User.create!(:name => "Brazil")
10
+ end
11
+
12
+ def self.down
13
+ User.delete_all()
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ class CreateUsersOnMaster < ActiveRecord::Migration
2
+ def self.up
3
+ User.create!(:name => "Master")
4
+ end
5
+
6
+ def self.down
7
+ User.delete_all
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsersOnCanada < ActiveRecord::Migration
2
+ using(:canada)
3
+
4
+ def self.up
5
+ User.create!(:name => "Sharding")
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsersOnBothShards < ActiveRecord::Migration
2
+ using(:canada, :brazil)
3
+
4
+ def self.up
5
+ User.create!(:name => "Both")
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsersOnShardsOfAGroup < ActiveRecord::Migration
2
+ history_shard(:country_shard)
3
+
4
+ def self.up
5
+ User.create!(:name => "Group")
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all()
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsersOnMultiplesGroups < ActiveRecord::Migration
2
+ history_shard('country_shard', 'history_shard')
3
+
4
+ def self.up
5
+ User.create!(:name => "MultipleGroup")
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all()
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class RaiseExceptionWithInvalidShardName < ActiveRecord::Migration
2
+ using(:amazing_shard)
3
+
4
+ def self.up
5
+ User.create!(:name => "Error")
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all()
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class RaiseExceptionWithInvalidMultipleShardNames < ActiveRecord::Migration
2
+ using(:brazil, :invalid_shard)
3
+
4
+ def self.up
5
+ User.create!(:name => "Error")
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all()
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class RaiseExceptionWithInvalidGroupName < ActiveRecord::Migration
2
+ history_shard(:invalid_group)
3
+
4
+ def self.up
5
+ User.create!(:name => "Error")
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all()
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class RaiseExceptionWithMultipleInvalidGroupNames < ActiveRecord::Migration
2
+ history_shard(:country_shard,:invalid_group)
3
+
4
+ def self.up
5
+ User.create!(:name => "Error")
6
+ end
7
+
8
+ def self.down
9
+ User.delete_all()
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require "mysql2"
4
+ require "active_record"
5
+ require "action_controller"
6
+ require "xbar"
7
+ require "support/xbar_helper"
8
+ require "support/database_models"
9
+
10
+ MIGRATIONS_ROOT = File.expand_path(File.join(File.dirname(__FILE__), 'migrations'))
11
+
12
+ XBar.directory = File.expand_path("../../spec", __FILE__)
13
+
14
+ RSpec.configure do |config|
15
+
16
+ config.before(:each) do
17
+ XBar.stub!(:directory).and_return(File.dirname(__FILE__))
18
+ end
19
+
20
+ config.after(:each) do
21
+ clean_all_shards
22
+ XBar::Mapper.reset(xbar_env: 'default', app_env: 'test')
23
+ end
24
+
25
+ end
@@ -0,0 +1,78 @@
1
+ # Rails 3.1 needs to do some introspection around the base class, which requires
2
+ # the model be a descendent of ActiveRecord::Base.
3
+ class BlankModel < ActiveRecord::Base; end;
4
+
5
+ class User < ActiveRecord::Base
6
+ def awesome_queries
7
+ XBar.using(:canada) do
8
+ User.create(:name => "teste")
9
+ end
10
+ end
11
+ end
12
+
13
+ class Client < ActiveRecord::Base
14
+ unreplicated_model
15
+ has_many :items
16
+ has_many :comments, :as => :commentable
17
+ end
18
+
19
+ class Cat < ActiveRecord::Base
20
+ using :china
21
+ end
22
+
23
+ #This class sets its own connection
24
+ class CustomConnection < ActiveRecord::Base
25
+ xbar_establish_connection(:adapter => "mysql2", :database => "rogue",
26
+ :username => "root", :password => "")
27
+ end
28
+
29
+ #This items belongs to a client
30
+ class Item < ActiveRecord::Base
31
+ belongs_to :client
32
+ has_many :parts
33
+ end
34
+
35
+ class Part < ActiveRecord::Base
36
+ belongs_to :item
37
+ end
38
+
39
+ class Keyboard < ActiveRecord::Base
40
+ validates_uniqueness_of :name
41
+ belongs_to :computer
42
+ end
43
+
44
+ class Computer < ActiveRecord::Base
45
+ has_one :keyboard
46
+ end
47
+
48
+ class Role < ActiveRecord::Base
49
+ has_and_belongs_to_many :permissions
50
+ end
51
+
52
+ class Permission < ActiveRecord::Base
53
+ has_and_belongs_to_many :roles
54
+ end
55
+
56
+ class Assignment < ActiveRecord::Base
57
+ belongs_to :programmer
58
+ belongs_to :project
59
+ end
60
+
61
+ class Programmer < ActiveRecord::Base
62
+ has_many :assignments
63
+ has_many :projects, :through => :assignments
64
+ end
65
+
66
+ class Project < ActiveRecord::Base
67
+ has_many :assignments
68
+ has_many :programmers, :through => :assignments
69
+ end
70
+
71
+ class Comment < ActiveRecord::Base
72
+ belongs_to :commentable, :polymorphic => true
73
+ end
74
+
75
+
76
+ class Bacon < ActiveRecord::Base
77
+ xbar_set_table_name "yummy"
78
+ end
@@ -0,0 +1,42 @@
1
+ def clean_all_shards
2
+ if proxy = Thread.current[:connection_proxy]
3
+ tables = ['schema_migrations', 'users', 'clients', 'cats', 'items', 'keyboards',
4
+ 'computers', 'permissions_roles', 'roles', 'permissions', 'assignments',
5
+ 'projects', 'programmers', "yummy"]
6
+ proxy.shards.keys.each do |key|
7
+ tables.each do |t|
8
+ BlankModel.using(key).connection.execute("DELETE FROM #{t}")
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ def clean_connection_proxy
15
+ Thread.current[:connection_proxy] = nil
16
+ end
17
+
18
+ def migrating_to_version(version, &block)
19
+ puts "migrating to version called version = #{version}"
20
+ ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT, version)
21
+ yield
22
+ ensure
23
+ ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT, version)
24
+ end
25
+
26
+ def using_environment(environment, &block)
27
+ prev_env = XBar::Mapper.app_env
28
+ XBar::Mapper.reset(xbar_env: 'default', app_env: environment.to_s)
29
+ yield
30
+ ensure
31
+ XBar::Mapper.reset(xbar_env: 'default', app_env: prev_env)
32
+ end
33
+
34
+ def set_xbar_env(xbar_env, app_env = nil)
35
+ opts = {xbar_env: xbar_env.to_s, :clear_cache => true}
36
+ if app_env && !defined?(Rails)
37
+ opts[:app_env] = app_env.to_s
38
+ end
39
+ XBar::Mapper.reset(opts)
40
+ # Not needed because reset should clean, I think.
41
+ #Thread.current[:connection_proxy].clean_proxy if Thread.current[:connection_proxy]
42
+ end