Module: LOM::Mapper

Defined in:
lib/lom/mapper.rb,
lib/lom/mapper.rb

Overview

Class methods to be injected in the class being mapped, and performs initialization thanks to #extend_object

Defined Under Namespace

Modules: InstanceMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extend_object(o) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/lom/mapper.rb', line 89

def self.extend_object(o)
    super
    o.include Mapper::InstanceMethods
    o.extend  Enumerable
    o.const_set(:Filtered, LOM::Filtered)
    o.__ldap_init
end

Instance Method Details

#__ldap_initObject



97
98
99
100
101
102
103
104
105
106
107
# File 'lib/lom/mapper.rb', line 97

def __ldap_init
    @__ldap_branch    = nil
    @__ldap_prefix    = nil
    @__ldap_scope     = :one
    @__ldap_filter    = nil
    @__ldap_attrs     = nil
    @__ldap_from      = nil
    @__ldap_to        = nil
    @__ldap_list      = []
    @__ldap_lh        = nil
end

#_ldap_to_obj(entry) ⇒ Object

Raises:



222
223
224
225
226
227
228
# File 'lib/lom/mapper.rb', line 222

def _ldap_to_obj(entry)
    raise EntryNotFound if entry.nil?
    entry.extend(EntryEnhanced)       
    args  = entry.instance_exec(entry, &_ldap_from)
    args  = [ args ] unless args.kind_of?(Array)
    self.new(*args)
end

#all(&rawfilter) ⇒ Array<Object>

Retrieve matching data as a list of object

Returns:

  • (Array<Object>)


309
310
311
# File 'lib/lom/mapper.rb', line 309

def all(&rawfilter)
    each(:object, rawfilter: rawfilter).to_a
end

#delete!(name) ⇒ Object



337
338
339
340
# File 'lib/lom/mapper.rb', line 337

def delete!(name)
    dn    = ldap_dn_from_id(name)
    lh.delete(:dn => dn)
end

#each(type = :object, filter: nil, rawfilter: nil, paged: nil) {|obj_or_id| ... } ⇒ Enumerator, self

Note:

If using ‘rawfilter`, no optimization will be performed aned the ldap attributes will be retrieved, even if desired type is :id

Iterate over matching data.

Parameters:

  • type (:object, :id) (defaults to: :object)

    return object or id

  • filter (String) (defaults to: nil)

    extra ldap search filter

  • rawfilter (Proc) (defaults to: nil)

    filter on ldap entry

  • paged (Array<Integer,Integer>) (defaults to: nil)

    pagination information

Yield Parameters:

  • obj_or_id (Object, String)

    ldap converted element according to type

Returns:

  • (Enumerator)

    if no block given

  • (self)

    if block given



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/lom/mapper.rb', line 247

def each(type = :object, filter: nil, rawfilter: nil, paged: nil)
    # Create Enumerator if no block given
    unless block_given?
        return enum_for(:each, type,
                        filter: filter, rawfilter: rawfilter, paged: paged)
    end

    # Merging filters
    filter  = Net::LDAP.filter('&', *[ filter, _ldap_filter ].compact)

    # Define attributes/converter according to selected type
    attributes, converter =
        case type
        when :id     then [ rawfilter ? _ldap_attrs : :dn,
                            ->(e) { ldap_dn_to_id(e.dn) }
                          ]
        when :object then [ _ldap_attrs,
                            ->(e) { _ldap_to_obj(e)     }
                          ]
        else raise ArgumentError, 'type must be either :object or :id'
        end

    
    # Paginate
    # XXX: pagination is emulated, should be avoided
    skip, count = if paged
                      page, page_size = paged
                      [ (page - 1) * page_size, page_size ]
                  end
    
    # Perform search
    lh.search(:base       => _ldap_branch,
              :filter     => filter,
              :attributes => attributes,
              :scope      => _ldap_scope) {|entry|

        if rawfilter && !rawfilter.call(entry)
            next
        elsif paged.nil?
            yield(converter.(entry))
        elsif skip > 0
            skip -= 1
        elsif count <= 0
            break
        else
            count -= 1
            yield(converter.(entry))
        end                
    }

    # Return self
    self
end

#exists?(name) ⇒ Boolean

Test existence of entry

Parameters:

  • param (String)

    entry name

Returns:

  • (Boolean)


364
365
366
367
# File 'lib/lom/mapper.rb', line 364

def exists?(name)
    dn    = ldap_dn_from_id(name)
    lh.get(:dn => dn, :return_result => false)
end

#fetch(name) ⇒ Object

Fetch the requested entry.

Parameters:

  • param (String)

    entry name

Returns:

  • (Object)

Raises:



329
330
331
332
333
334
335
# File 'lib/lom/mapper.rb', line 329

def fetch(name)
    dn    = ldap_dn_from_id(name)
    attrs = _ldap_attrs
    entry = lh.get(:dn => dn, :attributes => attrs)

    _ldap_to_obj(entry)
end

#get(name) ⇒ nil, Object Also known as: []

Get the requested entry. Same as #fetch but return nil if not found

Parameters:

  • param (String)

    entry name

Returns:

  • (nil)

    entry not found

  • (Object)


350
351
352
353
354
# File 'lib/lom/mapper.rb', line 350

def get(name)
    fetch(name)
rescue LOM::EntryNotFound
    nil
end

#ldap_attrs(*v) ⇒ Object



169
170
171
# File 'lib/lom/mapper.rb', line 169

def ldap_attrs(*v)
    @__ldap_attrs = v
end

#ldap_branch(v = nil) ⇒ Object



151
152
153
154
# File 'lib/lom/mapper.rb', line 151

def ldap_branch(v = nil)
    return _ldap_branch if v.nil?
    @__ldap_branch = v
end

#ldap_dn_from_id(id) ⇒ Object



218
219
220
# File 'lib/lom/mapper.rb', line 218

def ldap_dn_from_id(id)
    Net::LDAP::DN.new(_ldap_prefix.to_s, id, _ldap_branch).to_s
end

#ldap_dn_to_id(dn) ⇒ String?

Convert a dn to it’s corresponding id the current mapping.

Returns:

  • (String)

    id

  • (nil)

    dn is not from this mapping

Raises:

  • (Error)

    dn belongs to this mapping (it is in the mapping branch), but is malformed (not a direct child, or wrong prefix)



203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/lom/mapper.rb', line 203

def ldap_dn_to_id(dn)
    prefix = _ldap_prefix.to_s
    branch = _ldap_branch
    
    if sub = Net::LDAP::DN.sub?(dn, branch)
        case prefix
        when String, Symbol
            k, v, _ = sub.to_a
            raise Error, "not a direct child" if _
            raise Error, "wrong prefix"       if k.casecmp(prefix) != 0
            v
        end
    end
end

#ldap_filter(v) ⇒ Object



165
166
167
# File 'lib/lom/mapper.rb', line 165

def ldap_filter(v)
    @__ldap_filter = v[0] == '(' ? v : "(#{v})"
end

#ldap_from(p = nil, &b) ⇒ Object

Note:

block will be executed in the Net::LDAP::Entry instance



174
175
176
177
178
179
180
# File 'lib/lom/mapper.rb', line 174

def ldap_from(p=nil, &b)
    if (! p.nil? ^ b.nil?) || (p && !p.kind_of?(Proc))
        raise ArgumentError,
              'one and only one of proc/lamba/block need to be defined'
    end
    @__ldap_from = p || b
end

#ldap_list(name, body = nil, &block) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/lom/mapper.rb', line 134

def ldap_list(name, body=nil, &block)
    if body && block
        raise ArgumentError
    elsif body.nil? && block.nil?
        raise ArgumentError
    elsif block
        body = block
    end
        
    @__ldap_list << name
    define_singleton_method(name) do |*args|
        filter = body.call(*args)
        LOM::Filtered.new(filter, src: self)
    end
end

#ldap_listingArray<Symbol>

Return the list of defined list (using ldap_list).

Returns:

  • (Array<Symbol>)

    list of defined ldap list



130
131
132
# File 'lib/lom/mapper.rb', line 130

def ldap_listing
    @__ldap_list
end

#ldap_prefix(v = nil) ⇒ Object



156
157
158
159
# File 'lib/lom/mapper.rb', line 156

def ldap_prefix(v = nil)
    return _ldap_prefix if v.nil?
    @__ldap_prefix = v
end

#ldap_scope(v) ⇒ Object



161
162
163
# File 'lib/lom/mapper.rb', line 161

def ldap_scope(v)
    @__ldap_scope = v
end

#ldap_to(p = nil, &b) ⇒ Object

Note:

block will be executed in the mapped object instance



183
184
185
186
187
188
189
190
191
# File 'lib/lom/mapper.rb', line 183

def ldap_to(p=nil, &b)
    return _ldap_to if p.nil? && b.nil?

    if (! p.nil? ^ b.nil?) || (p && !p.kind_of?(Proc))
        raise ArgumentError,
              'one and only one of proc/lamba/block need to be defined'
    end
    @__ldap_to = p || b
end

#lhObject

Get the LDAP handler to use

In order of preference:

  • the handler set using lh=

  • the LH constant in this scope or parent scope

  • the one provided by LOM.lh



117
118
119
# File 'lib/lom/mapper.rb', line 117

def lh
    @__ldap_lh || const_get(:LH) || LOM.lh
end

#lh=(lh) ⇒ Object

Set the LDAP handler to use



122
123
124
# File 'lib/lom/mapper.rb', line 122

def lh=(lh)
    @__ldap_lh = lh
end

#list(&rawfilter) ⇒ Array<String>

Retrieve matching data as a list of id

Returns:

  • (Array<String>)


317
318
319
# File 'lib/lom/mapper.rb', line 317

def list(&rawfilter)
    each(:id, rawfilter: rawfilter).to_a
end

#paginate(page, page_size) ⇒ Object



301
302
303
# File 'lib/lom/mapper.rb', line 301

def paginate(page, page_size)
    LOM::Filtered.new(src: self, paged: [ page, page_size ])
end