Class: DataMapper::Adapters::FilemakerAdapter

Inherits:
AbstractAdapter
  • Object
show all
Defined in:
lib/dm-filemaker-adapter/adapter.rb

Defined Under Namespace

Modules: ModelMethods, ResourceMethods

Constant Summary collapse

VERSION =
DataMapper::FilemakerAdapter::VERSION
FMRESULTSET_TEMPLATE =
{:template => File.expand_path('../dm-fmresultset.yml', __FILE__)}

Instance Method Summary collapse

Instance Method Details

#aggregate(query) ⇒ Object

Takes a query and returns number of matched records. An empty query will return the total record count



77
78
79
80
81
82
83
84
85
86
# File 'lib/dm-filemaker-adapter/adapter.rb', line 77

def aggregate(query)
  #query.model.last_query = query
  #y query
  _layout = layout(query.model)
  opts = query.fmp_options
  #opts[:template] = self.class.fmresultset_template_path
  prms = query.to_fmp_query
  #[prms.empty? ? _layout.all(:max_records=>0).foundset_count : _layout.count(prms)]
  [prms.empty? ? _layout.view.total_count : _layout.count(prms)]
end

#create(resources) ⇒ Integer

Persists one or many new resources

Adapters provide specific implementation of this method

Examples:

adapter.create(collection)  # => 1

Parameters:

  • resources (Enumerable<Resource>)

    The list of resources (model instances) to create

Returns:

  • (Integer)

    The number of records that were actually saved into the data-store



29
30
31
32
33
34
35
36
37
38
39
# File 'lib/dm-filemaker-adapter/adapter.rb', line 29

def create(resources)
  #resources[0].model.last_query = resources
  counter = 0
  resources.each do |resource|
    fm_params = prepare_fmp_attributes(resource.dirty_attributes)
    rslt = layout(resource.model).create(fm_params)
    merge_fmp_response(resource, rslt[0])
    counter +=1
  end
  counter
end

#delete(collection) ⇒ Integer

Deletes one or many existing resources

Adapters provide specific implementation of this method

Examples:

adapter.delete(collection)  # => 1

Parameters:

  • collection (Collection)

    collection of records to be deleted

Returns:

  • (Integer)

    the number of records deleted



131
132
133
134
135
136
137
138
# File 'lib/dm-filemaker-adapter/adapter.rb', line 131

def delete(collection)
  counter = 0
  collection.each do |resource|
    rslt = layout(resource.model).delete(resource.instance_variable_get(:@_record_id))
    counter +=1
  end
  counter
end

#layout(model) ⇒ Object

Create fmp layout object from model object.



145
146
147
148
# File 'lib/dm-filemaker-adapter/adapter.rb', line 145

def layout(model)
  #Rfm.layout(model.storage_name, options.symbolize_keys)   #query.repository.adapter.options.symbolize_keys)
  model.layout
end

#prepare_fmp_attributes(attributes, *args) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/dm-filemaker-adapter/adapter.rb', line 150

def prepare_fmp_attributes(attributes, *args)
	options = args.last.is_a?(Hash) ? args.pop : {}
	prepend, append = options[:prepend], options[:append]
	fm_attributes = {}
	#puts "PREPARE FMP ATTRIBUTES"
	#puts attributes.to_yaml
	
	
	# Handles attributes that are relationships.
	attributes.dup.each do |key, val|
		# If an attribute is a relationship,
		# convert it to a key=>val that can be passed to Rfm.
		# Note that DM will eager-load related records of a collection all at once,
		# instead of one-at-a-time as you loop thru parent records.
		# In this case, the val of a relationship attribute will be a collection of parent records,
		# instead of just one parent record.
		# Example: "product_type.each {|type| puts type.products.size}"
		# Note that this variation will create n+1 queries "product_type.each {|type| puts type.products.count}"
		if key.class.name[/Relationship/]
			parent_keys = key.parent_key.to_a   #.collect(){|p| p.name}
			child_keys = key.child_key.to_a     #.collect(){|p| p.name}
			#puts "RELATIONSHIP PARENT #{key.parent_model_name} #{parent_keys.inspect}"
			#puts "RELATIONSHIP CHILD #{key.child_model_name} #{child_keys.inspect}"
			#puts "RELATIONSHIP CRITERIA #{val.inspect}"
			child_keys.each_with_index do |k, i|
				# The value dup is necessary, else the original data of parent resource will be modified.
				attributes[k] = Array(val).collect{|v| v[parent_keys[i].name].tap{|x| x.dup rescue x} }
				attributes.delete key
			end
		end
	end
	
	#puts "ATTRIBUTES BEFORE attributes_as_fields"
	#y attributes
	attributes_as_fields(attributes).each do |key, val|
		#puts "EACH ATTRIBUTE class #{val.class.name}"
		#puts "EACH ATTRIBUTE value #{val}"
		new_val = val && [val.is_a?(Fixnum) ? val : val.dup].flatten.inject([]) do |r, v|
			#puts "INJECTING v"
			#puts v
			new_v = v.respond_to?(:_to_fm) ? v._to_fm : v
			#puts "CONVERTING VAL #{new_val} TO STRING"
			new_v = new_v.to_s
			#puts "PREPENDING #{new_v} with '#{prepend}'"
			new_v.prepend prepend if prepend rescue nil
			new_v.append append if append rescue nil
			r << new_v
		end
		#puts "NEW_VAL"
		#puts new_val
		fm_attributes[key] = (new_val && new_val.size < 2) ? new_val[0] : new_val
	end
	#puts "FM_ATTRIBUTES OUTPUT"
	#puts fm_attributes
	fm_attributes
end

#read(query) ⇒ Enumerable<Hash>

Reads one or many resources from a datastore

Adapters provide specific implementation of this method

def read(query)

raise NotImplementedError, "#{self.class}#read not implemented"

end

Examples:

adapter.read(query)  # => [ { 'name' => 'Dan Kubb' } ]

Parameters:

  • query (Query)

    the query to match resources in the datastore

Returns:

  • (Enumerable<Hash>)

    an array of hashes to become resources



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/dm-filemaker-adapter/adapter.rb', line 59

def read(query)
  #query.model.last_query = query
  #puts query.to_yaml
  _layout = layout(query.model)
  opts = query.fmp_options
  #puts "ADAPTER#READ fmp options: #{opts.inspect}"
  #opts[:template] = self.class.fmresultset_template_path
  prms = query.to_fmp_query
  #puts "ADAPTER#READ fmpquery: #{prms.inspect}"
  #puts "ADAPTER#READ layout config: #{_layout.get_config.inspect}"
  rslt = prms.empty? ? _layout.all(opts) : _layout.find(prms, opts)
  # This was here to make rfm records loadable by dm, but no longer needed with Rfm#record @loaded disabled in parsing template.
  #rslt.collect{|r| Hash.new.merge(r) }
  #rslt.to_a
end

#update(attributes, collection) ⇒ Integer

Updates one or many existing resources

Adapters provide specific implementation of this method

Examples:

adapter.update(attributes, collection)  # => 1

Parameters:

  • attributes (Hash(Property => Object))

    hash of attribute values to set, keyed by Property

  • collection (Collection)

    collection of records to be updated

Returns:

  • (Integer)

    the number of records updated



104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/dm-filemaker-adapter/adapter.rb', line 104

def update(attributes, collection)
  #collection[0].model.last_query = [attributes, collection]
  fm_params = prepare_fmp_attributes(attributes)
  counter = 0
  collection.each do |resource|
    rslt = layout(resource.model).edit(resource.instance_variable_get(:@_record_id), fm_params)
    merge_fmp_response(resource, rslt[0])
    resource.persistence_state = DataMapper::Resource::PersistenceState::Clean.new resource
    counter +=1
  end
  counter        
end