Module: ActiveRecord::IdRegions::ClassMethods

Defined in:
lib/active_record/id_regions.rb

Instance Method Summary collapse

Instance Method Details

#clear_region_cacheObject



43
44
45
# File 'lib/active_record/id_regions.rb', line 43

def clear_region_cache
  @@my_region_number = nil
end

#compress_id(id) ⇒ Object



98
99
100
101
102
# File 'lib/active_record/id_regions.rb', line 98

def compress_id(id)
  return nil if id.nil?
  region_number, short_id = split_id(id)
  (region_number == 0) ? short_id.to_s : "#{region_number}#{COMPRESSED_ID_SEPARATOR}#{short_id}"
end

#compressed_id?(id) ⇒ Boolean

ID compression

Returns:

  • (Boolean)


94
95
96
# File 'lib/active_record/id_regions.rb', line 94

def compressed_id?(id)
  id.to_s =~ /^#{CID_OR_ID_MATCHER}$/
end

#group_ids_by_region(ids) ⇒ Object



123
124
125
# File 'lib/active_record/id_regions.rb', line 123

def group_ids_by_region(ids)
  ids.group_by { |id| id_to_region(id) }
end

#id_in_current_region?(id) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/active_record/id_regions.rb', line 76

def id_in_current_region?(id)
  id_to_region(id) == my_region_number
end

#id_in_region(id, region_number) ⇒ Object



51
52
53
# File 'lib/active_record/id_regions.rb', line 51

def id_in_region(id, region_number)
  region_number * rails_sequence_factor + id
end

#id_to_region(id) ⇒ Object



47
48
49
# File 'lib/active_record/id_regions.rb', line 47

def id_to_region(id)
  id.to_i / rails_sequence_factor
end

#in_my_regionObject



64
65
66
# File 'lib/active_record/id_regions.rb', line 64

def in_my_region
  in_region(my_region_number)
end

#in_region(region_number) ⇒ Object



68
69
70
# File 'lib/active_record/id_regions.rb', line 68

def in_region(region_number)
  region_number.nil? ? all : where(:id => region_to_range(region_number))
end

#my_region_number(force_reload = false) ⇒ Object



16
17
18
19
# File 'lib/active_record/id_regions.rb', line 16

def my_region_number(force_reload = false)
  clear_region_cache if force_reload
  @@my_region_number ||= discover_my_region_number
end

#partition_ids_by_remote_region(ids) ⇒ Object

Partition the passed ids into local and remote sets



119
120
121
# File 'lib/active_record/id_regions.rb', line 119

def partition_ids_by_remote_region(ids)
  ids.partition { |id| self.id_in_current_region?(id) }
end

#partition_objs_by_remote_region(objs) ⇒ Object

Partition the passed AR objects into local and remote sets



114
115
116
# File 'lib/active_record/id_regions.rb', line 114

def partition_objs_by_remote_region(objs)
  objs.partition(&:in_current_region?)
end

#rails_sequence_end(region_number = my_region_number) ⇒ Object



33
34
35
# File 'lib/active_record/id_regions.rb', line 33

def rails_sequence_end(region_number = my_region_number)
  rails_sequence_start(region_number) + rails_sequence_factor - 1
end

#rails_sequence_factorObject



21
22
23
# File 'lib/active_record/id_regions.rb', line 21

def rails_sequence_factor
  @@rails_sequence_factor ||= DEFAULT_RAILS_SEQUENCE_FACTOR
end

#rails_sequence_factor=(factor) ⇒ Object



25
26
27
# File 'lib/active_record/id_regions.rb', line 25

def rails_sequence_factor=(factor)
  @@rails_sequence_factor = factor
end

#rails_sequence_range(region_number = my_region_number) ⇒ Object Also known as: region_to_range



37
38
39
# File 'lib/active_record/id_regions.rb', line 37

def rails_sequence_range(region_number = my_region_number)
  rails_sequence_start(region_number)..rails_sequence_end(region_number)
end

#rails_sequence_start(region_number = my_region_number) ⇒ Object



29
30
31
# File 'lib/active_record/id_regions.rb', line 29

def rails_sequence_start(region_number = my_region_number)
  region_number * rails_sequence_factor
end

#region_number_from_sequenceObject



127
128
129
130
131
# File 'lib/active_record/id_regions.rb', line 127

def region_number_from_sequence
  sequence_name = connection.select_value("SELECT relname FROM pg_class WHERE relkind = 'S' LIMIT 1")
  return if sequence_name.nil?
  id_to_region(connection.select_value("SELECT last_value FROM #{sequence_name}"))
end

#region_to_array(region_number) ⇒ Object



59
60
61
62
# File 'lib/active_record/id_regions.rb', line 59

def region_to_array(region_number)
  range = region_to_range(region_number)
  [range.first, range.last]
end

#region_to_conditions(region_number, col = "id") ⇒ Object



55
56
57
# File 'lib/active_record/id_regions.rb', line 55

def region_to_conditions(region_number, col = "id")
  ["#{col} >= ? AND #{col} <= ?", *region_to_array(region_number)]
end

#split_id(id) ⇒ Object



80
81
82
83
84
85
86
87
88
# File 'lib/active_record/id_regions.rb', line 80

def split_id(id)
  return [my_region_number, nil] if id.nil?
  id = uncompress_id(id)

  region_number = id_to_region(id)
  short_id      = (region_number == 0) ? id : id % (region_number * rails_sequence_factor)

  return region_number, short_id
end

#uncompress_id(compressed_id) ⇒ Object



104
105
106
107
# File 'lib/active_record/id_regions.rb', line 104

def uncompress_id(compressed_id)
  return nil if compressed_id.nil?
  compressed_id.to_s =~ RE_COMPRESSED_ID ? ($1.to_i * rails_sequence_factor + $2.to_i) : compressed_id.to_i
end

#with_region(region_number) ⇒ Object



72
73
74
# File 'lib/active_record/id_regions.rb', line 72

def with_region(region_number)
  where(:id => region_to_range(region_number)).scoping { yield }
end