Class: SequelDM::DAO

Inherits:
Object
  • Object
show all
Defined in:
lib/sequel_dm/dao.rb

Class Method Summary collapse

Class Method Details

.associate(type, name, opts = OPTS, &block) ⇒ Object



87
88
89
90
91
# File 'lib/sequel_dm/dao.rb', line 87

def associate(type, name, opts = OPTS, &block)
  super.tap do
    set_dataset(eager(name))
  end
end

.def_one_to_many(opts) ⇒ Object

Raises:

  • (Error)


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
50
51
52
53
54
55
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
# File 'lib/sequel_dm/dao.rb', line 17

def def_one_to_many(opts)
  one_to_one = opts[:type] == :one_to_one
  name = opts[:name]
  model = self
  key = (opts[:key] ||= opts.default_key)
  km = opts[:key_method] ||= opts[:key]
  cks = opts[:keys] = Array(key)
  opts[:key_methods] = Array(opts[:key_method])
  primary_key = (opts[:primary_key] ||= self.primary_key)
  opts[:eager_loader_key] = primary_key unless opts.has_key?(:eager_loader_key)
  cpks = opts[:primary_keys] = Array(primary_key)
  pkc = opts[:primary_key_column] ||= primary_key
  pkcs = opts[:primary_key_columns] ||= Array(pkc)
  raise(Error, "mismatched number of keys: #{cks.inspect} vs #{cpks.inspect}") unless cks.length == cpks.length
  uses_cks = opts[:uses_composite_keys] = cks.length > 1
  slice_range = opts.slice_range
  opts[:dataset] ||= proc do
    opts.associated_dataset.where(opts.predicate_keys.zip(cpks.map{|k| send(k)}))
  end
  opts[:eager_loader] = proc do |eo|
    h = eo[:id_map]
    rows = eo[:rows]
    reciprocal = opts.reciprocal
    klass = opts.associated_class
    filter_keys = opts.predicate_key
    ds = model.eager_loading_dataset(opts, klass.where(filter_keys=>h.keys), nil, eo[:associations], eo)
    assign_singular = true if one_to_one
    case opts.eager_limit_strategy
    when :distinct_on
      ds = ds.distinct(*filter_keys).order_prepend(*filter_keys)
    when :window_function
      delete_rn = true
      rn = ds.row_number_column
      ds = apply_window_function_eager_limit_strategy(ds, opts)
    when :ruby
      assign_singular = false if one_to_one && slice_range
    end
    ds.all do |assoc_record|
      assoc_record.values.delete(rn) if delete_rn
      hash_key = uses_cks ? km.map{|k| assoc_record.send(k)} : assoc_record.send(km)
      next unless objects = h[hash_key]
      if assign_singular
        objects.each do |object|
          unless object.send(name)
            # TODO: add persistance_associations update here
            object.send("#{name}=", assoc_record)
            assoc_record.send("#{reciprocal}=", object) if reciprocal
          end
        end
      else
        objects.each do |object|
          add_to_associations_state(object, name, assoc_record)
          object.send(name).push(assoc_record)
          assoc_record.send("#{reciprocal}=", object) if reciprocal
        end
      end
    end
    if opts.eager_limit_strategy == :ruby
      if one_to_one
        if slice_range
          rows.each{|o| o.associations[name] = o.associations[name][slice_range.begin]}
        end
      else
        rows.each{|o| o.associations[name] = o.associations[name][slice_range] || []}
      end
    end
  end
  super
end

.delete(entity) ⇒ Object



167
168
169
170
171
# File 'lib/sequel_dm/dao.rb', line 167

def delete(entity)
  key_condition = prepare_key_condition_from_entity(entity)
  dataset.where(key_condition).delete
  delete_associations(entity)
end

.delete_all(entities) ⇒ Object

TODO: refactor



174
175
176
177
178
179
180
181
182
183
184
# File 'lib/sequel_dm/dao.rb', line 174

def delete_all(entities)
  entity_ids = entities.map(&:id)
  dataset.where(id: entity_ids).delete
  unless association_reflections.empty?
    association_reflections.each do |association, options|
      association_dao = options[:class]
      conditions = (options[:conditions] || {}).merge(options[:key] => entity_ids)
      association_dao.where(conditions).delete
    end
  end
end

.insert(entity, root = nil) ⇒ Object

Database methods



109
110
111
112
113
114
115
116
# File 'lib/sequel_dm/dao.rb', line 109

def insert(entity, root = nil)
  raw = mapper.to_hash(entity, root)
  key = dataset.insert(raw)
  set_entity_primary_key(entity, raw, key)
  save_state(entity, raw)
  insert_associations(entity)
  entity
end

.insert_all(entities, root = nil) ⇒ Object



118
119
120
121
122
# File 'lib/sequel_dm/dao.rb', line 118

def insert_all(entities, root = nil)
  entities.each do |entity|
    insert(entity, root)
  end
end

.multi_insert(entities) ⇒ Object



124
125
126
127
128
129
130
# File 'lib/sequel_dm/dao.rb', line 124

def multi_insert(entities)
  raws = []
  entities.each do |entity|
    raws << mapper.to_hash(entity)
  end
  dataset.multi_insert(raws)
end

.save(entity, root = nil) ⇒ Object



153
154
155
156
157
158
159
# File 'lib/sequel_dm/dao.rb', line 153

def save(entity, root = nil)
  if has_persistance_state?(entity)
    update(entity, root)
  else
    insert(entity, root)
  end
end

.save_all(entities, root = nil) ⇒ Object



161
162
163
164
165
# File 'lib/sequel_dm/dao.rb', line 161

def save_all(entities, root = nil)
  entities.each do |entity|
    save(entity, root)
  end
end

.set_dataset_row_proc(ds) ⇒ Object



93
94
95
96
97
98
99
100
# File 'lib/sequel_dm/dao.rb', line 93

def set_dataset_row_proc(ds)
  ds.row_proc = Proc.new do |raw|
    raise StandardError, "Mapper should be specified" if !self.mapper
    entity = self.mapper.to_entity(raw)
    save_state(entity, raw)
    entity
  end
end

.set_mapper(mapper) ⇒ Object



102
103
104
105
# File 'lib/sequel_dm/dao.rb', line 102

def set_mapper(mapper)
  SequelDM::ArgsValidator.is_class!(mapper, :mapper)
  self.mapper = mapper
end

.update(entity, root = nil) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/sequel_dm/dao.rb', line 132

def update(entity, root = nil)
  raw = mapper.to_hash(entity, root)
  raw = select_only_changed_values(entity, raw)

  unless raw.empty?
    update_state(entity, raw)

    key_condition = prepare_key_condition_from_entity(entity)
    dataset.where(key_condition).update(raw)
  end

  insert_or_update_associations(entity)
  entity
end

.update_all(entities, root = nil) ⇒ Object



147
148
149
150
151
# File 'lib/sequel_dm/dao.rb', line 147

def update_all(entities, root = nil)
  entities.each do |entity|
    update(entity, root)
  end
end