Module: StorageHandler

Included in:
Entities
Defined in:
lib/qooxview/storage_handler.rb

Overview

Holds all DataTypes for an entity

Instance Method Summary collapse

Instance Method Details

#add_new_storage(st, config = {}) ⇒ Object

Adds a new storage type - returns the new created or already initialised storage-type



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/qooxview/storage_handler.rb', line 48

def add_new_storage(st, config = {})
  st = replace_st(st)

  if !StorageType.has? st
    dputs(0) { "Can't find StorageType of -#{st.inspect}-" }
    exit 1
  end

  if has_storage? st
    dputs(3) { "Storage-type -#{st}- already exists" }
  else
    dputs(3) { "Adding storage-type -#{st}-" }
    @storage[st] = StorageType.new_st(st, self, config)
    dputs(3) { "@storage is #{@storage.inspect}" }
  end

  @storage[st]
end

#add_value_to_storage(value) ⇒ Object

Adds a new value to the storages to hold the appropriate values.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/qooxview/storage_handler.rb', line 21

def add_value_to_storage(value)
  return if !value.st
  args = value.args.merge(:dtype => value.dtype)
  if value.st != 'ALL'
    st = replace_st(value.st)
    if not @storage.has_key? st
      # A request for another type
      add_new_storage(st)
    end
    @storage[st].add_field(value.name, args)
  else
    @storage.each { |k, v|
      v.add_field(value.name, args)
    }
  end
end

#create(args, allow_double = false) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/qooxview/storage_handler.rb', line 219

def create(args, allow_double = false)
  # dputs_func
  oldload = @loading
  @loading = true
  if args.class != Hash
    dputs(0) { "Entities.create takes a hash! You gave a #{args.class}" }
    exit
  end
  dputs(5) { "Data_field_id is #{@data_field_id}" }
  if not args[@data_field_id]
    nid = new_id[@data_field_id]
    dputs(3) { "Adding data_field_id of #{nid}" }
    args.merge!({@data_field_id => nid})
  end

  # Ask every storage-type whether he wants to change something in the
  # data
  dputs(3) { "Asking storages to intervene for #{self.class.name}" }
  @storage.each { |k, di|
    dputs(3) { "Intervention from #{k.inspect}" }
    di.data_create(args)
  }
  data_id = args[@data_field_id].to_i
  if not @data[data_id] or allow_double
    if @data[data_id]
      dputs(0) { "Error: creating double-entry #{args.inspect}" }
    end
    @data[data_id] = {@data_field_id => data_id}
    dputs(5) { "@data is now #{@data.inspect}" }
    dputs(5) { "data_class is now #{@data_class.to_s}" }
    args.each { |k, v|
      set_entry(data_id, k, v)
    }
    @save_after_create and save
    update_key(data_id)
    d = get_data_instance(data_id)
    @changed = d.changed = true
    @loading = oldload
    return d
  else
    @storage.each { |k, di| di.data_double(args) }
    dputs(2) { "Trying to create a double entry with data_id #{args[@data_field_id]}!" }
    @loading = oldload
    return nil
  end
end

#create_key(name) ⇒ Object



462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'lib/qooxview/storage_handler.rb', line 462

def create_key(name)
  name = name.to_sym
  if @keys.has_key? name
    dputs(2) { "#{self.class.name} already has key #{name}" }
  else
    entries = {}
    @data.each_pair { |k, v|
      dputs(5) { "Adding #{name} = #{v[name]} in #{v.inspect}" }
      entries[v[name].to_s] = k
    }
    dputs(4) { "Setting keys[#{name}] to #{entries.inspect}" }
    @keys[name] = entries
  end
end

#data_update(id) ⇒ Object



362
363
364
365
366
367
# File 'lib/qooxview/storage_handler.rb', line 362

def data_update(id)
  @data[id.to_i].each { |f, v|
    dputs(5) { "Updating data for #{id} - #{f}" }
    get_entry(id, f)
  }
end

#delete_all(local_only = false) ⇒ Object



448
449
450
451
452
453
454
455
456
457
458
459
460
# File 'lib/qooxview/storage_handler.rb', line 448

def delete_all(local_only = false)
  dputs(3) { "Deleting all of #{self.class.name}" }
  @data_instances = {}
  @data = {}
  @keys = {}
  @storage.each { |k, di|
    di.delete_all(local_only)
  }
  @static = Statics.get_hash("Entities.#{@name}")
  @last_id = 1
  @is_loaded = false
  @dont_migrate = false
end

#delete_id(id) ⇒ Object



291
292
293
294
295
296
297
298
299
300
# File 'lib/qooxview/storage_handler.rb', line 291

def delete_id(id)
  id = id.to_i
  dputs(3) { "Deleting id #{id}" }
  @data.delete(id)
  @data_instances.delete(id)
  @storage.each{|k, di|
    di.delete id
  }
  @changed = true
end

#field_args(name) ⇒ Object



38
39
40
41
42
43
44
45
# File 'lib/qooxview/storage_handler.rb', line 38

def field_args(name)
  @storage.each { |k, v|
    if v.has_field name
      return v.field_args name
    end
  }
  nil
end

#filter_by(filter) ⇒ Object

filter is a hash with field/value-pairs to be searched.



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/qooxview/storage_handler.rb', line 191

def filter_by(filter)
  keys = filter.keys
  key = keys.shift
  res = search_by(key, filter[key]).collect { |r| r.data }
  # Refine the search
  keys.each { |k|
    res = res.select { |r|
      dputs(5) { "Searching results for #{[r, k, filter[k]].inspect}" }
      r.has_key? k and r[k].to_s =~ /#{filter[k].to_s}/i
    }
  }
  res.map{|r|
    get_data_instance(r[@data_field_id])
  }
end

#find(field, value) ⇒ Object



95
96
97
98
# File 'lib/qooxview/storage_handler.rb', line 95

def find(field, value)
  result = find_by(field, value)
  return result ? result.data : nil
end

#find_by(field, value) ⇒ Object



100
101
102
103
# File 'lib/qooxview/storage_handler.rb', line 100

def find_by(field, value)
  key = find_key_by(field, value)
  return key ? get_data_instance(key) : nil
end

#find_key_by(field, value) ⇒ Object

Have a handler for the ActiveRecord-type match_by_ and the name of the field to search for



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/qooxview/storage_handler.rb', line 82

def find_key_by(field, value)
  #dputs( 5 ){ "( #{field}, #{value} ) with #{@data.inspect}" }
  @data.each_key { |k|
    dputs(5) { "Searching :#{value}: in #{field} of #{k} which is "+
        ":#{@data[k][field.to_sym].to_s}: " }
    #if @data[k] and @data[k][field.to_sym].to_s.downcase == value.to_s.downcase
    if @data[k] and (@data[k][field.to_sym].to_s =~ /#{value.to_s}/i)
      return k
    end
  }
  return nil
end

#firstObject



492
493
494
495
# File 'lib/qooxview/storage_handler.rb', line 492

def first
  key = @data.first
  return key ? get_data_instance(key[0]) : nil
end

#get_entry(id, field) ⇒ Object



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/qooxview/storage_handler.rb', line 336

def get_entry(id, field)
  field = field.to_sym
  id = id.to_i
  # First look if there is a non-caching DataStorage
  @storage.each { |k, di|
    dputs(5) { "Storage is #{di}" }
    if di.has_field field and not di.data_cache
      dputs(4) { "#{di} doesn't have data_cache for #{id} - #{field}" }
      val = di.get_entry(id, field)
      if val.class == String
        val.force_encoding(Encoding::UTF_8)
      end
      dputs(4) { "#{id} - #{field} - #{val.inspect}" }
      @data[id][field] = val
      return val
    end
  }

  # Else get the things out of the cache
  if @data[id] and @data[id][field]
    @data[id][field]
  else
    nil
  end
end

#has_field?(f) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
74
75
76
77
78
# File 'lib/qooxview/storage_handler.rb', line 71

def has_field?(f)
  @storage.each { |k, v|
    if v.has_field f
      return true
    end
  }
  return false
end

#has_storage?(st) ⇒ Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/qooxview/storage_handler.rb', line 67

def has_storage?(st)
  @storage ? (@storage.has_key? st.to_sym) : false
end

#lastObject



497
498
499
500
# File 'lib/qooxview/storage_handler.rb', line 497

def last
  key = @data.last
  return key ? get_data_instance(key[0]) : nil
end

#load(has_static = true) ⇒ Object



406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/qooxview/storage_handler.rb', line 406

def load(has_static = true)
  #dputs_func
  return if @is_loaded
  dep = RPCQooxdooService.needs["Entities.#{self.class.name}"]
  dputs(2) { "Loading #{self.class.name} - #{dep}" }
  if dep
    dep.each { |pre|
      pre_class = RPCQooxdooService.services[pre]
      pre_class.is_loaded and next
      dputs(3) { "Pre-loading #{pre}" }
      pre_class.load
    }
  end
  @data = {}
  @data_instances = {}
  @keys = {}
  @storage.each { |k, di|
    dputs(5) { "Loading #{k} at #{di.name} with #{di.inspect}" }
    @data.merge!(di.load) { |_, o, n| o.merge(n) }
    dputs(5) { "Loaded #{@data.inspect} for #{self.name}" }
  }
  if @data.length == 0 && respond_to?(:init)
    dputs(1) { "Calling init for #{self.name}" }
    init
    @dont_migrate = true
  end
  @last_id = @data.length > 0 ? @data.to_a.last[0] : 1
  has_static and @static = Statics.get_hash("Entities.#{@name}")

  @is_loaded = true
  respond_to?(:loaded) and loaded
end

#match_by(field, value) ⇒ Object

Like search_by, but only ONE EXACT match



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/qooxview/storage_handler.rb', line 167

def match_by(field, value)
  field = field.to_sym
  v = value.is_a?(Entity) ? value.id : value.to_s
  @data.each_key { |k|
    if @data[k]
      [@data[k][field]].flatten.each { |d|
        dputs(5) { "Searching #{v} in #{d} of #{@data[k].inspect}" }
        if d.to_s == v
          dputs(4) { "Found data-entry #{k}: #{@data[k].inspect}" }
          return get_data_instance(k)
        end
      }
    end
  }
  return nil
end

#match_key(name, entry) ⇒ Object



477
478
479
480
481
482
483
# File 'lib/qooxview/storage_handler.rb', line 477

def match_key(name, entry)
  dputs(5) { "Matching #{entry} of #{name} in #{@keys.inspect}" }
  name = name.to_sym
  @keys.has_key? name or create_key(name)
  e = entry.is_a?(Entity) ? entry.id.to_s : entry.to_s
  get_data_instance(@keys[name][e])
end

#matches_by(field, value) ⇒ Object

Like search_by, but only EXACT matcheS



185
186
187
188
# File 'lib/qooxview/storage_handler.rb', line 185

def matches_by(field, value)
  ret = search_by(field, "^#{value}$")
  return ret
end

#migrateObject



369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/qooxview/storage_handler.rb', line 369

def migrate
  #dputs_func
  if not mv = MigrationVersions.match_by(:class_name, @name)
    dputs(2) { "#{@name.inspect} has no migration yet" }
    mv = Entities.MigrationVersions.create(:class_name => @name,
                                           :version => 0)
  end
  version = mv.version + 1
  dputs(3) { "Checking for migration_#{version} of #{@name}" }
  while self.respond_to?(vers_str = "migration_#{version}".to_sym) ||
      self.respond_to?(vers_str = "migration_#{version}_raw".to_sym)
    if @dont_migrate
      log_msg :Migration, "Just counting migrations for #{name}: #{version}"
    else
      # log_msg :Migration, "Migrating #{@name} to version #{version}, calling #{vers_str}"
      dputs(4) { "Working on #{data.inspect}" }
      @data.each { |k, v|
        if vers_str.to_s =~ /_raw$/
          dputs(4) { "Sending raw data of #{v.inspect}" }
          send vers_str, v
          dputs(4) { "raw data is now #{v.inspect}" }
          #@data[k] = v
        else
          inst = get_data_instance(k)
          dputs(4) { "Sending #{inst.inspect}" }
          send vers_str, inst
        end
      }
      dputs(5) { "Data is now #{@data.inspect}" }
      @changed = true
    end
    mv.version = version
    version += 1
  end
  @changed and save
end

#new_idObject



207
208
209
210
211
212
213
214
215
216
217
# File 'lib/qooxview/storage_handler.rb', line 207

def new_id
  #    last_id = 1
  #    if @data.keys.length > 0
  #      last_id = @data.keys.max{|a,b| a.to_i <=> b.to_i} + 1
  #    end
  while @data.has_key? @last_id
    dputs(5) { "Already having id #{@last_id}" }
    @last_id += 1
  end
  return {@data_field_id => @last_id}
end

#replace_st(st) ⇒ Object

Checks whether there is a configuration-option which wants to replace the StorageType



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/qooxview/storage_handler.rb', line 8

def replace_st(st)
  if get_config(false, :StorageHandler, :Replace)
    $config[:StorageHandler][:Replace].each { |k, v|
      if st.to_sym == k.to_sym
        dputs(3) { "Replacing #{k.inspect} with #{v.inspect}" }
        st = v.to_sym
      end
    }
  end
  st.to_sym
end

#saveObject



439
440
441
442
443
444
445
446
# File 'lib/qooxview/storage_handler.rb', line 439

def save
  return unless @changed
  @storage.each { |k, di|
    dputs(5) { "Saving #{k} at #{di.inspect}" }
    di.save(@data)
  }
  @changed = false
end

#save_data(d) ⇒ Object



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/qooxview/storage_handler.rb', line 266

def save_data(d)
  # dputs_func
  dputs(5) { "Saving #{d.inspect}" }
  d.to_sym!
  if d.has_key? @data_field_id
    # Assure that the data_field_id is an integer
    dputs(5) { 'Has key' }
    data_id = d[@data_field_id].to_i
    d[@data_field_id] = data_id
    e = get_data_instance(data_id)
    if not e
      dputs(0) { "Didn't find key #{data_id.inspect}" }
      exit 1
    else
      dputs(5) { "Setting hash #{d.inspect}" }
      e.data_set_hash(d, true)
    end
  else
    e = create(d)
  end

  save
  return e.data
end

#search_allObject

Searching of misuse in search_all - found and accepted misuses can take search_all_



113
114
115
116
# File 'lib/qooxview/storage_handler.rb', line 113

def search_all
  # log_msg :StorageHandler, "Search_all for #{self.name} in #{caller.inspect}"
  search_all_
end

#search_all_Object



105
106
107
108
109
# File 'lib/qooxview/storage_handler.rb', line 105

def search_all_
  @data.each_key.collect { |k|
    get_data_instance(k)
  }
end

#search_by(field, value) ⇒ Object

Similar to find_by, but searches multiple instances that are similar to the value, returns the instances



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/qooxview/storage_handler.rb', line 120

def search_by(field, value)
  result = []
  field = field.to_sym
  @data.each_key { |k|
    #dputs( 5 ){ "Searching :#{value}: in #{field} of #{k} which is :#{@data[k][field.to_sym]}:" }
    if @data[k]
      [@data[k][field]].flatten.each { |d|
        if d.to_s =~ /#{value.to_s}/i
          dputs(4) { "Found data-entry #{k}: #{@data[k].inspect}" }
          result.push get_data_instance(k)
        end
      }
    end
  }
  return result.uniq
end

#search_by_all(field, values) ⇒ Object

Similar to search_by, but searches multiple instances that contain all elements of ‘values’



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/qooxview/storage_handler.rb', line 139

def search_by_all(field, values)
  #dputs_func
  result = []
  field = field.to_sym
  @data.each_key { |k|
    #dputs( 5 ){ "Searching :#{value}: in #{field} of #{k} which is :#{@data[k][field.to_sym]}:" }
    if @data[k]
      found_data = true
      values.each { |value|
        found = false
        [@data[k][field]].flatten.each { |d|
          dputs(4) { "Searching for #{value.inspect} in #{k}: #{d.inspect}" }
          if d.to_s =~ /#{value.to_s}/i
            found = true
          end
        }
        found_data &= found
      }
      if found_data
        dputs(4) { "Found data-entry #{k}: #{@data[k].inspect}" }
        result.push get_data_instance(k)
      end
    end
  }
  return result.uniq
end

#set_entry(id, field, v) ⇒ Object



302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/qooxview/storage_handler.rb', line 302

def set_entry(id, field, v)
  #dputs_func
  value = if v.is_a? Entity
            dputs(3) { "Converting #{v} to #{v.id}" }
            v.id
          elsif v.is_a? Array
            dputs(3) { "Storing an array #{v.inspect}" }
            v.collect { |val|
              val.is_a?(Entity) ? val.id : val
            }
          else
            v
          end
  field = field.to_sym
  dputs(4) { "Storing #{value} in #{field} for id #{id} in data #{@data}" }
  @storage.each { |k, di|
    if di.has_field field
      if !@data[id.to_i].has_key?(field) or
          value.to_s != @data[id.to_i][field].to_s
        val = di.set_entry(id, field, value)
        dputs(4) { "#{id} - #{field} - #{value.inspect}" }
        @data[id.to_i][field] = val
      elsif DEBUG_LVL >= 4
        log_msg 'StorageHandler', 'Trying to overwrite with same value in ' +
                                    "#{self.class.name}-#{field}-#{value.to_s}\n" +
                                    caller.inspect
      end
      update_key(id.to_i)
      return val
    end
  }
  nil
end

#update_key(id) ⇒ Object



485
486
487
488
489
490
# File 'lib/qooxview/storage_handler.rb', line 485

def update_key(id)
  dputs(5) { "Updating keys #{@keys.inspect} for #{id}" }
  @keys.each_key { |k|
    @keys[k].merge!(@data[id][k].to_s => id)
  }
end