Class: ActiveRecord::ModelSpaces::Context

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/active_record/model_spaces/context.rb

Overview

holds the current and working tables for a ModelSpace

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

all_model_superclasses, class_for_classname, class_from_classname, is_active_record_model?, model_from_name, name_from_model, require_for_classname

Constructor Details

#initialize(model_space, model_space_key, persistor) ⇒ Context

Returns a new instance of Context.



18
19
20
21
22
23
24
# File 'lib/active_record/model_spaces/context.rb', line 18

def initialize(model_space, model_space_key, persistor)
  @model_space = model_space
  @model_space_key = model_space_key.to_sym
  @persistor = persistor
  read_versions
  create_tables
end

Instance Attribute Details

#current_model_versionsObject (readonly)

Returns the value of attribute current_model_versions.



15
16
17
# File 'lib/active_record/model_spaces/context.rb', line 15

def current_model_versions
  @current_model_versions
end

#model_spaceObject (readonly)

Returns the value of attribute model_space.



12
13
14
# File 'lib/active_record/model_spaces/context.rb', line 12

def model_space
  @model_space
end

#model_space_keyObject (readonly)

Returns the value of attribute model_space_key.



13
14
15
# File 'lib/active_record/model_spaces/context.rb', line 13

def model_space_key
  @model_space_key
end

#persistorObject (readonly)

Returns the value of attribute persistor.



14
15
16
# File 'lib/active_record/model_spaces/context.rb', line 14

def persistor
  @persistor
end

#working_model_versionsObject (readonly)

Returns the value of attribute working_model_versions.



16
17
18
# File 'lib/active_record/model_spaces/context.rb', line 16

def working_model_versions
  @working_model_versions
end

Class Method Details

.drop_tables(model_space, model_space_key) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/active_record/model_spaces/context.rb', line 39

def self.drop_tables(model_space, model_space_key)
  model_space.registered_model_keys.map do |model_name|
    m = Util.model_from_name(model_name)
    tm = TableManager.new(m)

    all_table_names = (0..model_space.history_versions(m)).map do |v|
      TableNames.table_name(model_space.name, model_space_key, model_space.base_table_name(m), model_space.history_versions(m), v)
    end

    all_table_names.each do |table_name|
      tm.drop_table(table_name)
    end
  end
end

Instance Method Details

#base_table_name(model) ⇒ Object

base table name



61
62
63
# File 'lib/active_record/model_spaces/context.rb', line 61

def base_table_name(model)
  model_space.base_table_name(model)
end

#commitObject



155
156
157
# File 'lib/active_record/model_spaces/context.rb', line 155

def commit
  persistor.update_model_space_model_versions(model_space.name, model_space_key, current_model_versions.merge(working_model_versions))
end

#create_tablesObject



31
32
33
34
35
36
37
# File 'lib/active_record/model_spaces/context.rb', line 31

def create_tables
  model_space.registered_model_keys.map do |model_name|
    m = Util.model_from_name(model_name)
    tm = TableManager.new(m)
    tm.create_table(base_table_name(m), current_table_name(m))
  end
end

#current_table_name(model) ⇒ Object

current table_name, seen by everyone outside of this context



71
72
73
# File 'lib/active_record/model_spaces/context.rb', line 71

def current_table_name(model)
  table_name_from_model_version(model, get_current_model_version(model))
end

#hooverObject

copy all data to the base model-space tables and drop all history tables



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/active_record/model_spaces/context.rb', line 123

def hoover
  raise "can't hoover with active working versions: #{working_model_versions.keys.inspect}" if !working_model_versions.empty?

  model_names = model_space.registered_model_keys

  new_versions = Hash[ model_names.map do |model_name|
                         m = Util.model_from_name(model_name)
                         base_name = base_table_name(m)
                         current_name = current_table_name(m)
                         hoovered_name = hoovered_table_name(m)

                         tm = TableManager.new(m)

                         # copy to hoovered table
                         if current_name != hoovered_name
                           tm.recreate_table(base_name, hoovered_name)
                           tm.copy_table(current_name, hoovered_name)
                         end

                         # drop history tables
                         (1..model_space.history_versions(m)).map do |v|
                           htn = table_name_from_model_version(m, v)
                           tm.drop_table(htn)
                         end

                         [model_name, 0]
                       end ]
  persistor.update_model_space_model_versions(new_versions)

  read_versions
end

#hoovered_table_name(model) ⇒ Object

table_name for version 0



66
67
68
# File 'lib/active_record/model_spaces/context.rb', line 66

def hoovered_table_name(model)
  table_name_from_model_version(model, 0)
end

#new_version(model, copy_old_version = false, &block) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/active_record/model_spaces/context.rb', line 87

def new_version(model, copy_old_version=false, &block)
  raise "new_version: a block must be supplied" if !block

  if get_working_model_version(model)
    block.call # nothing to do
  else
    current_version = get_current_model_version(model)
    next_version = TableNames.next_version(model_space.history_versions(model), current_version)

    tm = TableManager.new(model)
    ok = false
    begin
      btn = base_table_name(model)
      ctn = current_table_name(model)
      ntn = next_table_name(model)
      if next_version != current_version
        tm.recreate_table(btn, ntn)
        tm.copy_table(ctn, ntn) if copy_old_version
      else # no history
        tm.truncate_table(ntn) if !copy_old_version
      end
      set_working_model_version(model, next_version)
      r = block.call
      ok = true
      r
    ensure
      delete_working_model_version(model) if !ok
    end
  end
end

#next_table_name(model) ⇒ Object

table_name which would be seen by this context in or after a new_version/updated_version. always returns a name



76
77
78
79
80
# File 'lib/active_record/model_spaces/context.rb', line 76

def next_table_name(model)
  current_version = get_current_model_version(model)
  next_version = TableNames.next_version(model_space.history_versions(model), current_version)
  table_name_from_model_version(model, next_version)
end

#read_versionsObject



26
27
28
29
# File 'lib/active_record/model_spaces/context.rb', line 26

def read_versions
  @current_model_versions = persistor.read_model_space_model_versions(model_space.name, model_space_key)
  @working_model_versions = {}
end

#table_name(model) ⇒ Object

implements the Model.table_name method



55
56
57
58
# File 'lib/active_record/model_spaces/context.rb', line 55

def table_name(model)
  version = get_working_model_version(model) || get_current_model_version(model)
  table_name_from_model_version(model, version)
end

#updated_version(model, &block) ⇒ Object



118
119
120
# File 'lib/active_record/model_spaces/context.rb', line 118

def updated_version(model, &block)
  new_version(model, true, &block)
end

#working_table_name(model) ⇒ Object

table_name of working table, seen by this context in or after new_version/updated_version. null if no new_version/updated_version has been issued/completed



83
84
85
# File 'lib/active_record/model_spaces/context.rb', line 83

def working_table_name(model)
  table_name_from_model_version(model, get_working_model_version(model)) if get_working_model_version(model)
end