Class: BackendEnumSource

Inherits:
Object
  • Object
show all
Defined in:
backend/app/model/backend_enum_source.rb

Constant Summary

@@enum_value_cache =
Rufus::Lru::SynchronizedHash.new(1024)
@@max_cache_ms =
5000

Class Method Summary (collapse)

Class Method Details

+ (Object) cache_entry_for(enum_name, force_refresh = false)



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'backend/app/model/backend_enum_source.rb', line 56

def self.cache_entry_for(enum_name, force_refresh = false)
  cached = @@enum_value_cache[enum_name]
  now = java.lang.System.currentTimeMillis

  if force_refresh || !cached || ((now - cached[:time]) > @@max_cache_ms)
    @@enum_value_cache[enum_name] = {
      :time => now,
      :entry => DB.open(true) do |db|

        value_to_id_map = {}
        id_to_value_map = {}
        editable = true 
        db[:enumeration].join(:enumeration_value, :enumeration_id => :id).
                         filter(:name => enum_name).
                         select(:value, Sequel.qualify(:enumeration_value, :id), :editable).
                         all.each do |row|
          value_to_id_map[row[:value]] = row[:id]
          id_to_value_map[row[:id]] = row[:value]
          editable = ( row[:editable] === 1 or row[:editable] == true )  
        end

        {
          :values => value_to_id_map.keys,
          :value_to_id_map => value_to_id_map,
          :id_to_value_map => id_to_value_map,
          :editable => editable 
        }
      end
    }
  end

  @@enum_value_cache[enum_name][:entry]
end

+ (Boolean) editable?(enum_name)

Returns:

  • (Boolean)


95
96
97
# File 'backend/app/model/backend_enum_source.rb', line 95

def self.editable?(enum_name)
  (  self.cache_entry_for(enum_name)[:editable] === 1 or self.cache_entry_for(enum_name)[:editable] == true )
end

+ (Object) id_for_value(enum_name, value)



100
101
102
103
104
105
106
107
108
# File 'backend/app/model/backend_enum_source.rb', line 100

def self.id_for_value(enum_name, value)
  result = self.cache_entry_for(enum_name)[:value_to_id_map][value]

  if !result
    result = self.cache_entry_for(enum_name, true)[:value_to_id_map][value]
  end

  result
end

+ (Boolean) valid?(enum_name, value)

Returns:

  • (Boolean)


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'backend/app/model/backend_enum_source.rb', line 5

def self.valid?(enum_name, value)
  if RequestContext.get(:create_enums)

    # Some cheeky caching on the RequestContext here.  The batch import
    # process can need to check/create an awful lot of enums, so don't insert
    # into the database unless we really need to.
    #
    created = RequestContext.get(:created_enums) || {}
    RequestContext.put(:created_enums, created)

    if !Array(created[enum_name]).include?(value)
      # The customer is always right!
      DB.open(true) do |db|
        enum_id = db[:enumeration].filter(:name => enum_name).select(:id).first[:id]

        raise "Couldn't find enum: #{enum_name}" if !enum_id

        DB.attempt {
          sibling = db[:enumeration_value].filter(:enumeration_id => enum_id).order(:position).last
          if sibling
            position = sibling[:position] + 1
          else
            position = 0
          end
          
          db[:enumeration_value].insert(:enumeration_id => enum_id,
                                        :value => value,
                                        :position => position)
          @@enum_value_cache.delete(enum_name)
          Enumeration.broadcast_changes
        }.and_if_constraint_fails do
          # Must already be there.  No problem.
        end
      end

      created[enum_name] ||= []
      created[enum_name] << value
    end

    true
  else
    self.values_for(enum_name).include?(value)
  end

end

+ (Object) value_for_id(enum_name, id)



124
125
126
127
128
129
130
131
132
133
134
# File 'backend/app/model/backend_enum_source.rb', line 124

def self.value_for_id(enum_name, id)
  return nil if id.nil?

  result = self.cache_entry_for(enum_name)[:id_to_value_map][id]

  if !result
    self.cache_entry_for(enum_name, true)[:id_to_value_map][id]
  end

  result
end

+ (Object) values_for(enum_name)



91
92
93
# File 'backend/app/model/backend_enum_source.rb', line 91

def self.values_for(enum_name)
  self.cache_entry_for(enum_name)[:values]
end

+ (Object) values_for_ids(ids)



111
112
113
114
115
116
117
118
119
120
121
# File 'backend/app/model/backend_enum_source.rb', line 111

def self.values_for_ids(ids)
  result = {}

  DB.open(true) do |db|
    db[:enumeration_value].filter(:id => ids).each do |row|
      result[row[:id]] = row[:value]
    end
  end

  result
end