Class: Sengiri::Model::Base

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/sengiri/model/base.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = nil, options = {}) ⇒ Base

Returns a new instance of Base.



7
8
9
10
# File 'lib/sengiri/model/base.rb', line 7

def initialize(attributes = nil, options = {})
  @shard_name = self.class.shard_name
  super
end

Instance Attribute Details

#current_shardObject (readonly)

Returns the value of attribute current_shard.



5
6
7
# File 'lib/sengiri/model/base.rb', line 5

def current_shard
  @current_shard
end

Class Method Details

.belongs_to_with_sharding(name, scope = nil, options = {}) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/sengiri/model/base.rb', line 150

def belongs_to_with_sharding(name, scope = nil, options = {})
  class_name, scope, options = *prepare_association(name, scope, options)
  shard_classes.each do |klass|
    new_options = options.merge({
      class_name: class_name.to_s.classify + klass.shard_name,
      foreign_key: options[:foreign_key] || name.to_s.foreign_key
    })
    klass.belongs_to_without_sharding(name, scope, new_options)
  end
  belongs_to_without_sharding(name, scope, options)
end

.constantize(name) ⇒ Object



162
163
164
# File 'lib/sengiri/model/base.rb', line 162

def constantize(name)
  name.to_s.singularize.classify.constantize
end

.dbconfsObject



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sengiri/model/base.rb', line 67

def dbconfs
  if defined? Rails
    @dbconfs ||= Rails.application.config.database_configuration.select {|name|
      /^#{@sharding_group_name}/ =~ name
    }.select {|name|
      /#{env}#{@sharding_database_suffix}$/ =~ name
    }

  end
  @dbconfs
end

.envObject



116
117
118
# File 'lib/sengiri/model/base.rb', line 116

def env
  ENV["SENGIRI_ENV"] ||= ENV["RAILS_ENV"] || 'development'
end

.establish_shard_connection(name) ⇒ Object



120
121
122
# File 'lib/sengiri/model/base.rb', line 120

def establish_shard_connection(name)
  establish_connection dbconfs["#{@sharding_group_name}_shard_#{name}_#{env}#{@sharding_database_suffix}"]
end

.has_many_with_sharding(name, scope = nil, options = {}, &extension) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/sengiri/model/base.rb', line 124

def has_many_with_sharding(name, scope = nil, options = {}, &extension)
  class_name, scope, options = *prepare_association(name, scope, options)
  shard_classes.each do |klass|
    new_options = options.merge({
      class_name: class_name.to_s.classify + klass.shard_name,
      foreign_key: options[:foreign_key] || self.to_s.foreign_key
    })
    klass.has_many_without_sharding(name, scope, new_options, extension) if block_given?
    klass.has_many_without_sharding(name, scope, new_options) unless block_given?
  end
  has_many_without_sharding(name, scope, options, extension) if block_given?
  has_many_without_sharding(name, scope, options) unless block_given?
end

.has_one_with_sharding(name, scope = nil, options = {}) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/sengiri/model/base.rb', line 138

def has_one_with_sharding(name, scope = nil, options = {})
  class_name, scope, options = *prepare_association(name, scope, options)
  shard_classes.each do |klass|
    new_options = options.merge({
      class_name: class_name.to_s.classify + klass.shard_name,
      foreign_key: options[:foreign_key] || self.to_s.foreign_key
    })
    klass.has_one_without_sharding(name, scope, new_options)
  end
  has_one_without_sharding(name, scope, options)
end

.prepare_association(name, scope, options) ⇒ Object



166
167
168
169
170
171
172
173
174
# File 'lib/sengiri/model/base.rb', line 166

def prepare_association(name, scope, options)
  if scope.is_a?(Hash)
    options = scope
    scope   = nil
  end
  class_name = options[:class_name] || name
  constantize(class_name)
  [class_name, scope, options]
end

.shard(name) ⇒ Object



86
87
88
89
90
91
# File 'lib/sengiri/model/base.rb', line 86

def shard(name)
  if block_given?
    yield @shard_class_hash[name.to_s]
  end
  @shard_class_hash[name.to_s]
end

.shard_classesObject



29
30
31
32
# File 'lib/sengiri/model/base.rb', line 29

def shard_classes
  return @shard_class_hash.values if @shard_class_hash
  []
end

.shard_nameObject



26
# File 'lib/sengiri/model/base.rb', line 26

def shard_name         ; @shard_name          end

.shard_namesObject



79
80
81
82
83
84
# File 'lib/sengiri/model/base.rb', line 79

def shard_names
  @shard_names ||= dbconfs.map do |k,v|
    k.gsub("#{@sharding_group_name}_shard_", '').gsub(/_#{env}#{@sharding_database_suffix}$/, '')
  end
  @shard_names
end

.sharding_group(name, confs: nil, suffix: nil) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/sengiri/model/base.rb', line 34

def sharding_group(name, confs: nil, suffix: nil)
  @dbconfs = confs if confs
  @sharding_group_name = name
  @shard_class_hash = {}
  @sharding_database_suffix = if suffix.present? then "_#{suffix}" else nil end
  first = true
  raise "Databases are not found" if shard_names.blank?
  shard_names.each do |s|
    klass = Class.new(self)
    module_name = self.name.deconstantize
    module_name = "Object" if module_name.blank?
    module_name.constantize.const_set self.name.demodulize + s, klass
    klass.instance_variable_set :@shard_name, s
    klass.instance_variable_set :@dbconfs,    dbconfs
    klass.instance_variable_set :@sharding_group_name, name
    klass.instance_variable_set :@sharding_database_suffix, @sharding_database_suffix

    #
    # first shard shares connection with base class
    #
    if first
      establish_shard_connection s
    else
      klass.establish_shard_connection s
    end
    first = false
    if defined? Ardisconnector::Middleware
      Ardisconnector::Middleware.models << klass
    end
    @shard_class_hash[s] = klass
  end
end

.sharding_group_nameObject



27
# File 'lib/sengiri/model/base.rb', line 27

def sharding_group_name; @sharding_group_name end

.shards(&block) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/sengiri/model/base.rb', line 93

def shards(&block)
  transaction do
    shard_names.each do |shard_name|
      block.call shard(shard_name)
    end
  end
end

.transaction(klasses = shard_classes, &block) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/sengiri/model/base.rb', line 101

def transaction(klasses=shard_classes, &block)
  if shard_name
    super &block
  else
    if klasses.length > 0
      klass = klasses.pop
      klass.transaction do
        transaction klasses, &block
      end
    else
      yield
    end
  end
end

Instance Method Details

#narrowcast(association) ⇒ Object



20
21
22
23
# File 'lib/sengiri/model/base.rb', line 20

def narrowcast(association)
  foreign_key = self.class.table_name.singularize.foreign_key
  association.to_s.classify.constantize.shard(shard_name).where(foreign_key => id)
end

#shard_nameObject



16
17
18
# File 'lib/sengiri/model/base.rb', line 16

def shard_name
  self.class.instance_variable_get :@shard_name
end

#sharding_group_nameObject



12
13
14
# File 'lib/sengiri/model/base.rb', line 12

def sharding_group_name
  self.class.instance_variable_get :@sharding_group_name
end