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.
- data/Appraisals +25 -0
- data/README.mkdn +215 -0
- data/Rakefile +337 -1
- data/examples/README +5 -0
- data/examples/config/simple.json +22 -0
- data/examples/example1.rb +34 -0
- data/examples/migrations/1_create_users.rb +10 -0
- data/examples/setup.rb +43 -0
- data/gemfiles/rails3.gemfile +8 -0
- data/gemfiles/rails3.gemfile.lock +74 -0
- data/gemfiles/rails31.gemfile +8 -0
- data/gemfiles/rails31.gemfile.lock +83 -0
- data/gemfiles/rails32.gemfile +7 -0
- data/gemfiles/rails32.gemfile.lock +117 -0
- data/gemfiles/rails4.gemfile +9 -0
- data/gemfiles/rails4.gemfile.lock +134 -0
- data/lib/migrations/1_create_usage_statistics.rb +23 -0
- data/lib/xbar/association.rb +49 -0
- data/lib/xbar/association_collection.rb +69 -0
- data/lib/xbar/colors.rb +32 -0
- data/lib/xbar/has_and_belongs_to_many_association.rb +17 -0
- data/lib/xbar/logger.rb +14 -0
- data/lib/xbar/mapper.rb +304 -0
- data/lib/xbar/migration.rb +76 -0
- data/lib/xbar/model.rb +165 -0
- data/lib/xbar/proxy.rb +249 -0
- data/lib/xbar/rails2/association.rb +133 -0
- data/lib/xbar/rails2/persistence.rb +39 -0
- data/lib/xbar/rails3/arel.rb +13 -0
- data/lib/xbar/rails3/association.rb +112 -0
- data/lib/xbar/rails3/persistence.rb +37 -0
- data/lib/xbar/rails3.1/singular_association.rb +34 -0
- data/lib/xbar/scope_proxy.rb +55 -0
- data/lib/xbar/shard.rb +95 -0
- data/lib/xbar/version.rb +2 -2
- data/lib/xbar.rb +121 -2
- data/run +27 -0
- data/spec/config/acme.json +53 -0
- data/spec/config/connection.rb +2 -0
- data/spec/config/default.json +160 -0
- data/spec/config/duplicate_shard.json +21 -0
- data/spec/config/missing_key.json +20 -0
- data/spec/config/new_shards.json +29 -0
- data/spec/config/no_master_shard.json +19 -0
- data/spec/config/not_entire_sharded.json +23 -0
- data/spec/config/octopus.json +27 -0
- data/spec/config/octopus_rails.json +25 -0
- data/spec/config/production_fully_replicated.json +21 -0
- data/spec/config/production_raise_error.json +17 -0
- data/spec/config/simple.json +22 -0
- data/spec/config/single_adapter.json +20 -0
- data/spec/console.rb +15 -0
- data/spec/migrations/10_create_users_using_replication.rb +12 -0
- data/spec/migrations/11_add_field_in_all_slaves.rb +11 -0
- data/spec/migrations/12_create_users_using_block.rb +23 -0
- data/spec/migrations/13_create_users_using_block_and_using.rb +15 -0
- data/spec/migrations/1_create_users_on_master.rb +9 -0
- data/spec/migrations/2_create_users_on_canada.rb +11 -0
- data/spec/migrations/3_create_users_on_both_shards.rb +11 -0
- data/spec/migrations/4_create_users_on_shards_of_a_group.rb +11 -0
- data/spec/migrations/5_create_users_on_multiples_groups.rb +11 -0
- data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +11 -0
- data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +11 -0
- data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +11 -0
- data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +11 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/database_models.rb +78 -0
- data/spec/support/xbar_helper.rb +42 -0
- data/spec/xbar/association_spec.rb +660 -0
- data/spec/xbar/controller_spec.rb +40 -0
- data/spec/xbar/logger_spec.rb +22 -0
- data/spec/xbar/mapper_spec.rb +283 -0
- data/spec/xbar/migration_spec.rb +110 -0
- data/spec/xbar/model_spec.rb +434 -0
- data/spec/xbar/proxy_spec.rb +124 -0
- data/spec/xbar/replication_spec.rb +94 -0
- data/spec/xbar/scope_proxy_spec.rb +22 -0
- data/spec/xbar/shard_spec.rb +36 -0
- data/xbar.gemspec +13 -3
- 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,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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|