ginjo-rfm 3.0.8 → 3.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3a124ce5cf138e1c46547069cc547a46f4692827
4
- data.tar.gz: 597d7eaa2f436d8d224340f2d3bdb4a090b8113f
3
+ metadata.gz: d2a03d23cf578b34173f800b1658fe22465b2736
4
+ data.tar.gz: 02f0520fabc22fdaf653d02b1afa1b43867e65c9
5
5
  SHA512:
6
- metadata.gz: 00974925e3e0434eb7056421575f35d4bf2e567e79eb6c9a8b4d88d42d39cba3ed77514d0aaa592e148aaf541c1abdbbffbe381ab4805ab64f510c9b6371b5aa
7
- data.tar.gz: 3c9fe4a727cae3c8d24fa4ccef9244ec9edb82522bb7a227c3b95c8ddbdd5654102ed197b0bf8b7cc077c729ef308810d0ff36270ab0dc1f3b1c71844faadc09
6
+ metadata.gz: fd1ad124d35792b2959dbb3a6f82d0534c303dee8686df59cdf963e255778e843b32cab896437b8e07082d65a2b2f43bd8a27bc4f9a825c15fad892ac0f16773
7
+ data.tar.gz: dd657b7d1a9fd7c4b85728da57e29fe6d480733bcf7d4ad65f32fbe34e3c6e033148d715198e8c84bb08985f30ef9a0dbce4f0bedcba9d0925b5676c56fad0e2
@@ -1,10 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## Ginjo-Rfm 3.0.9
4
+
5
+ * Fixed bug in parser that was appending each portal array recursively to itself.
6
+
7
+ * Sax parser template option :template now takes a full-path string.
8
+
9
+ * Compatible with dm-filemaker-adapter (for DataMapper ORM).
10
+
11
+ * Config now recognizes :template option, allowing alternative parsing templates.
12
+
3
13
  ## Ginjo-Rfm 3.0.8
4
14
 
5
15
  * Implemented proxy option for database connections thru a proxy server.
6
16
 
7
- config :proxy=>['my.proxy.com', 8888]
17
+ config :proxy=>['my.proxy.com', 8888]
8
18
 
9
19
  * Implemented erb parsing of config.yml
10
20
 
@@ -212,8 +222,8 @@
212
222
 
213
223
  Example:
214
224
 
215
- server.db.all #=> ['dbname1', 'dbname2', ...]
216
- server.db #=> a DbFactory object (descendant of Hash), containing 0 or more Database objects
225
+ server.db.all #=> ['dbname1', 'dbname2', ...]
226
+ server.db #=> a DbFactory object (descendant of Hash), containing 0 or more Database objects
217
227
 
218
228
  ## Lardawge-Rfm 1.4.2 (unreleased)
219
229
 
@@ -221,8 +231,8 @@
221
231
 
222
232
  Example:
223
233
 
224
- Old: record.john #=> ""
225
- New: record.john #=> nil
234
+ Old: record.john #=> ""
235
+ New: record.john #=> nil
226
236
 
227
237
  ## Lardawge-Rfm 1.4.1.2
228
238
 
@@ -244,11 +254,11 @@
244
254
 
245
255
  Example:
246
256
 
247
- result = fm_server('layout').find({:username => "==#{username}"}, {:include_portals => true})
248
- # => This will fetch all records with portal records attached.
249
-
250
- result.first.portals
251
- # => would return an empty hash by default.
257
+ result = fm_server('layout').find({:username => "==#{username}"}, {:include_portals => true})
258
+ # => This will fetch all records with portal records attached.
259
+
260
+ result.first.portals
261
+ # => would return an empty hash by default.
252
262
 
253
263
  * Internal file restructuring. Some classes have changed but it should be nothing a developer would use API wise. Please let me know if it is.
254
264
 
data/README.md CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
  # ginjo-rfm
19
19
 
20
- Rfm is a Ruby-Filemaker adapter, a Ruby Gem that provides an interface between Filemaker Server and Ruby. Query your Filemaker database, browse result records as persistent objects, and create/update/delete records with a syntax similar to ActiveRecord. Ginjo-rfm picks up from the lardawge-rfm gem and continues to refine code and fix bugs. Version 3 removes the dependency on ActiveSupport and is now a completely independent Gem, able to run most of its core features without requiring any other supporting Gems. ActiveModel features can be activated by adding activemodel to your Gemfile (or requiring activemodel manually).
20
+ Rfm is a Ruby-Filemaker adapter, a gem that provides an interface between Filemaker Server and Ruby. Query your Filemaker database, browse result records as persistent objects, and create/update/delete records with a syntax similar to ActiveRecord. Ginjo-rfm picks up from the lardawge-rfm gem and continues to refine code and fix bugs. Version 3 removes the dependency on ActiveSupport and is now a completely independent Gem, able to run most of its core features without requiring any other supporting Gems. ActiveModel features can be activated by adding activemodel to your Gemfile (or requiring activemodel manually).
21
21
 
22
22
  Ginjo-rfm version 3 has been tested successfully on Ruby 1.8.7 thru 2.1.3.
23
23
 
@@ -1 +1 @@
1
- 3.0.8
1
+ 3.0.9
@@ -316,11 +316,13 @@ module Rfm
316
316
  else
317
317
  prms[new_key]=prms.delete(k) if new_key != k
318
318
  end
319
+ #puts "PRMS: #{new_key} #{prms[new_key].class} #{prms[new_key]}"
319
320
  end
320
321
 
321
322
  #c = Connection.new(action, prms, options, state.merge(:parent=>self))
322
323
  c = Connection.new(action, prms, options, self)
323
- rslt = c.parse(template || :fmresultset, Rfm::Resultset.new(self, self))
324
+ #rslt = c.parse(template || :fmresultset, Rfm::Resultset.new(self, self))
325
+ rslt = c.parse(template, Rfm::Resultset.new(self, self))
324
326
  capture_resultset_meta(rslt) unless @resultset_meta
325
327
  rslt
326
328
  end
@@ -21,11 +21,11 @@ module Rfm
21
21
  def portal_field_element_close_callback(cursor)
22
22
  resultset = cursor.top.object
23
23
  table, name = @attributes['name'].to_s.split('::')
24
- #puts ['DATUM_portal_callback_01', table, name].join(', ')
24
+ #puts ['DATUM_portal_field_element_close_callback_01', table, name].join(', ')
25
25
  name = get_mapped_name(name, resultset)
26
26
  field = resultset.portal_meta[table.downcase][name.downcase]
27
27
  data = @attributes['data']
28
- #puts ['DATUM_portal_callback_02', resultset.class, table, name, field, data].join(', ')
28
+ #puts ['DATUM_portal_field_element_close_callback_02', "cursor.parent.object.class: #{cursor.parent.object.class}", "resultset.class: #{resultset.class}", "table: #{table}", "name: #{name}", "field: #{field}", "data: #{data}"]
29
29
  #(puts resultset.portal_meta.to_yaml) unless field
30
30
  cursor.parent.object[name.downcase] = field.coerce(data)
31
31
  end
@@ -33,6 +33,7 @@ module Rfm
33
33
  log_parser
34
34
  use
35
35
  parent
36
+ template
36
37
  grammar
37
38
  field_mapping
38
39
  capture_strings_with
@@ -46,6 +46,7 @@ module Rfm
46
46
  :raise_on_401 => false,
47
47
  :timeout => 60,
48
48
  :ignore_bad_data => false,
49
+ :template => :fmresultset,
49
50
  :grammar => 'fmresultset'
50
51
  } #.merge(options)
51
52
 
@@ -78,7 +79,8 @@ module Rfm
78
79
  end
79
80
 
80
81
  def parse(template=nil, initial_object=nil, parser=nil, options={})
81
- (template = 'fmresultset.yml') unless template
82
+ template ||= state[:template]
83
+ #(template = 'fmresultset.yml') unless template
82
84
  #(template = File.join(File.dirname(__FILE__), '../sax/', template)) if template.is_a? String
83
85
  Rfm::SaxParser.parse(connect.body, template, initial_object, parser, state(*options)).result
84
86
  end
@@ -54,11 +54,12 @@
54
54
  #
55
55
  # YAML structure defining a SAX xml parsing template.
56
56
  # Options:
57
- # initialize_with: string, symbol, or array (object, method, params...). Should return new object. See Rfm::SaxParser::Cursor#get_callback.
57
+ # initialize_with: OBSOLETE? string, symbol, or array (object, method, params...). Should return new object. See Rfm::SaxParser::Cursor#get_callback.
58
58
  # elements: array of element hashes [{'name'=>'element-tag'},...]
59
59
  # attributes: array of attribute hashes {'name'=>'attribute-name'} UC
60
- # class: string-or-class: class name for new element
60
+ # class: string-or-class: class name for new element
61
61
  # attach: string: shared, _shared_var_name, private, hash, array, cursor, none - how to attach this element or attribute to #object.
62
+ # array: [0]string of above, [1..-1]new_element_callback options (see get_callback method).
62
63
  # attach_elements: string: same as 'attach' - how to attach ANY subelements to this model's object, unless they have their own 'attach' specification.
63
64
  # attach_attributes: string: same as 'attach' - how to attach ANY attributes to this model's object, unless they have their own 'attach' specification.
64
65
  # before_close: string, symbol, or array (object, method, params...). See Rfm::SaxParser::Cursor#get_callback.
@@ -66,7 +67,7 @@
66
67
  # delimiter: string: attribute/hash key to delineate objects with identical tags
67
68
  # create_accessors: string or array: all, private, shared, hash, none
68
69
  # accessor: string: all, private, shared, hash, none
69
- # element_handler: string, symbol, or array (object, method, params...). Should return new object. See Rfm::SaxParser::Cursor#get_callback.
70
+ # element_handler: NOT-USED? string, symbol, or array (object, method, params...). Should return new object. See Rfm::SaxParser::Cursor#get_callback.
70
71
  # Default attach prefs are 'cursor'.
71
72
  # Use this when all new-element operations should be offloaded to custom class or module.
72
73
  # Should return an instance of new object.
@@ -216,7 +217,7 @@ module Rfm
216
217
  end
217
218
 
218
219
  def receive_start_element(_tag, _attributes)
219
- #puts ["\nRECEIVE_START '#{_tag}'", "current_object: #{@object.class}", "current_model: #{@model}"]
220
+ #puts ["\nRECEIVE_START '#{_tag}'", "current_object: #{@object.class}", "current_model: #{@model['name']}", "attributes #{_attributes}"]
220
221
  new_cursor = Cursor.new(_tag, @handler, self, _attributes) #, binding)
221
222
  new_cursor.process_new_element(binding)
222
223
 
@@ -262,11 +263,15 @@ module Rfm
262
263
  @object = new_element || DEFAULT_CLASS.allocate
263
264
 
264
265
  if @initial_attributes && @initial_attributes.any? #&& @attribute_attachment_prefs != 'none'
266
+ #puts "PROCESS_NEW_ELEMENT calling assign_attributes with ATTRIBUTES #{@initial_attributes}"
265
267
  assign_attributes(@initial_attributes) #, @object, @model, @local_model)
266
268
  end
267
269
 
270
+ # If @local_model has a delimiter, defer attach_new_element until later.
271
+ #puts "PROCESS_NEW_ELEMENT delimiter of @local_model #{delimiter?(@local_model)}"
268
272
  if !delimiter?(@local_model)
269
273
  #attach_new_object(@parent.object, @object, @tag, @parent.model, @local_model, 'element')
274
+ #puts "PROCESS_NEW_ELEMENT calling attach_new_element with TAG #{@tag} and OBJECT #{@object}"
270
275
  attach_new_element(@tag, @object)
271
276
  end
272
277
  end
@@ -289,6 +294,7 @@ module Rfm
289
294
 
290
295
  if (delimiter = delimiter?(@local_model); delimiter && !['none','cursor'].include?(@element_attachment_prefs.to_s))
291
296
  #attach_new_object(@parent.object, @object, @tag, @parent.model, @local_model, 'element')
297
+ #puts "RECEIVE_END_ELEMENT attaching new element TAG (#{@tag}) OBJECT (#{@object.class}) #{@object.to_yaml} WITH LOCAL MODEL #{@local_model.to_yaml} TO PARENT (#{@parent.object.class}) #{@parent.object.to_yaml} PARENT MODEL #{@parent.model.to_yaml}"
292
298
  attach_new_element(@tag, @object)
293
299
  end
294
300
 
@@ -316,21 +322,22 @@ module Rfm
316
322
  end
317
323
 
318
324
  ### Parse callback instructions, compile & send callback method ###
325
+ ### TODO: This is way too convoluted. Document it better, or refactor!!!
319
326
  # This method will send a method to an object, with parameters, and return a new object.
320
- # Input: string, symbol, or array of strings
327
+ # Input (first param): string, symbol, or array of strings
321
328
  # Returns: object
322
329
  # Default options:
323
330
  # :object=>object
324
331
  # :method=>'a method name string or symbol'
325
332
  # :params=>"params string to be eval'd in context of cursor"
326
333
  # Usage:
327
- # callback: send a method (or eval string) to an object with parameters.
328
- # string: a string to be eval'd in context of current object.
329
- # symbol: method to be called on current object.
330
- # array: object, method, params.
331
- # object: <object or string>
332
- # method: <string or symbol>
333
- # params: <string>
334
+ # callback: send a method (or eval string) to an object with parameters, consisting of...
335
+ # string: a string to be eval'd in context of current object.
336
+ # or symbol: method to be called on current object.
337
+ # or array: object, method, params.
338
+ # object: <object or string>
339
+ # method: <string or symbol>
340
+ # params: <string>
334
341
  #
335
342
  # TODO-MAYBE: Change param order to (method, object, params),
336
343
  # might help confusion with param complexities.
@@ -460,7 +467,7 @@ module Rfm
460
467
  # # end
461
468
  # end
462
469
 
463
- def attach_new_element(name, new_object) #(base_object, new_object, name, base_model, new_model, type)
470
+ def attach_new_element(name, new_object) #old params (base_object, new_object, name, base_model, new_model, type)
464
471
  label = label_or_tag(name, @local_model)
465
472
 
466
473
  # Was this, which works fine, but not as efficient:
@@ -481,9 +488,8 @@ module Rfm
481
488
  # end
482
489
 
483
490
 
484
- #puts ["\nATTACH_NEW_ELEMENT 1", "type: #{type}", "label: #{label}", "base_object: #{base_object.class}", "new_object: #{new_object.class}", "delimiter: #{delimiter?(new_model)}", "prefs: #{prefs}", "shared_var_name: #{shared_var_name}", "create_accessors: #{create_accessors}"]
491
+ #puts ["\nATTACH_NEW_ELEMENT 1", "new_object: #{new_object}", "parent_object: #{@parent.object}", "label: #{label}", "delimiter: #{delimiter?(@local_model)}", "prefs: #{prefs}", "shared_var_name: #{shared_var_name}", "create_accessors: #{create_accessors}"]
485
492
  @parent.object._attach_object!(new_object, label, delimiter?(@local_model), prefs, 'element', :default_class=>DEFAULT_CLASS, :shared_variable_name=>shared_var_name, :create_accessors=>create_accessors)
486
- #puts ["\nATTACH_NEW_ELEMENT 2: #{base_object.class} with ", label, delimiter?(new_model), prefs, type, :shared_variable_name=>shared_var_name, :create_accessors=>create_accessors]
487
493
  # if type == 'attribute'
488
494
  # puts ["\nATTACH_ATTR", "name: #{name}", "label: #{label}", "new_object: #{new_object.class rescue ''}", "base_object: #{base_object.class rescue ''}", "base_model: #{base_model['name'] rescue ''}", "new_model: #{new_model['name'] rescue ''}", "prefs: #{prefs}"]
489
495
  # end
@@ -685,10 +691,12 @@ module Rfm
685
691
 
686
692
  # Does the heavy-lifting of template retrieval.
687
693
  def load_template(dat)
694
+ #puts "DAT: #{dat}, class #{dat.class}"
688
695
  prefix = defined?(TEMPLATE_PREFIX) ? TEMPLATE_PREFIX : ''
689
696
  #puts "SaxParser::Handler#load_template... 'prefix' is #{prefix}"
690
697
  rslt = case
691
698
  when dat.is_a?(Hash); dat
699
+ when (dat.is_a?(String) && dat[/^\//]); YAML.load_file dat
692
700
  when dat.to_s[/\.y.?ml$/i]; (YAML.load_file(File.join(*[prefix, dat].compact)))
693
701
  # This line might cause an infinite loop.
694
702
  when dat.to_s[/\.xml$/i]; self.class.build(File.join(*[prefix, dat].compact), nil, {'compact'=>true})
@@ -696,6 +704,8 @@ module Rfm
696
704
  when dat.is_a?(String); YAML.load dat
697
705
  else DEFAULT_CLASS.new
698
706
  end
707
+ #puts rslt
708
+ rslt
699
709
  end
700
710
 
701
711
  def result
@@ -892,7 +902,7 @@ class Object
892
902
 
893
903
  # Master method to attach any object to this object.
894
904
  def _attach_object!(obj, *args) # name/label, collision-delimiter, attachment-prefs, type, *options: <options>
895
- #puts ["\nATTACH_OBJECT._attach_object", self.class, obj.class, obj.to_s, args].to_yaml
905
+ #puts ["\nATTACH_OBJECT._attach_object", "self.class: #{self.class}", "obj.class: #{obj.class}", "obj.to_s: #{obj.to_s}", "args: #{args}"]
896
906
  options = ATTACH_OBJECT_DEFAULT_OPTIONS.merge(args.last.is_a?(Hash) ? args.pop : {}){|key, old, new| new || old}
897
907
  # name = (args[0] || options[:name])
898
908
  # delimiter = (args[1] || options[:delimiter])
@@ -915,6 +925,8 @@ class Object
915
925
  # else
916
926
  # self._merge_object!(obj, 'unknown_name', delimiter, prefs, type, options)
917
927
  # end
928
+ #puts ["\nATTACH_OBJECT RESULT", self.to_yaml]
929
+ #puts ["\nATTACH_OBJECT RESULT PORTALS", (self.portals.to_yaml rescue 'no portals')]
918
930
  end
919
931
 
920
932
  # Master method to merge any object with this object
@@ -939,7 +951,7 @@ class Object
939
951
 
940
952
  # Merge a named object with the specified instance variable of self.
941
953
  def _merge_instance!(obj, name, delimiter, prefs, type, options={})
942
- #puts ["\n_merge_instance!", self.class, obj.class, name, delimiter, prefs, type, options.keys, '_end_merge_instance!'].join(', ')
954
+ #puts ["\nOBJECT._merge_instance!", "self.class: #{self.class}", "obj.class: #{obj.class}", "name: #{name}", "delimiter: #{delimiter}", "prefs: #{prefs}", "type: #{type}", "options.keys: #{options.keys}", '_end_merge_instance!'] #.join(', ')
943
955
  rslt = if instance_variable_get("@#{name}") || delimiter
944
956
  if delimiter
945
957
  delimit_name = obj._get_attribute(delimiter, options[:shared_variable_name]).to_s.downcase
@@ -947,7 +959,13 @@ class Object
947
959
  #instance_variable_set("@#{name}", instance_variable_get("@#{name}") || options[:default_class].new)[delimit_name]=obj
948
960
  # This line is more efficient than the above line.
949
961
  instance_variable_set("@#{name}", options[:default_class].new) unless instance_variable_get("@#{name}")
950
- instance_variable_get("@#{name}")[delimit_name]=obj
962
+
963
+ # This line was active in 3.0.9.pre01, but it was inserting each portal array as an element in the array,
964
+ # after all the Rfm::Record instances had been added. This was causing an potential infinite recursion situation.
965
+ # I don't think this line was supposed to be here - was probably an older piece of code.
966
+ #instance_variable_get("@#{name}")[delimit_name]=obj
967
+
968
+ #instance_variable_get("@#{name}")._merge_object!(obj, delimit_name, nil, nil, nil)
951
969
  # Trying to handle multiple portals with same table-occurance on same layout.
952
970
  # In parsing terms, this is trying to handle multiple elements who's delimiter field contains the SAME delimiter data.
953
971
  instance_variable_get("@#{name}")._merge_delimited_object!(obj, delimit_name)
@@ -971,6 +989,8 @@ class Object
971
989
  end
972
990
 
973
991
  def _merge_delimited_object!(obj, delimit_name)
992
+ #puts "MERGING DELIMITED OBJECT self #{self.class} obj #{obj.class} delimit_name #{delimit_name}"
993
+
974
994
  case
975
995
  when self[delimit_name].nil?; self[delimit_name] = obj
976
996
  when self[delimit_name].is_a?(Hash); self[delimit_name].merge!(obj)
@@ -1053,7 +1073,7 @@ class Hash
1053
1073
 
1054
1074
  def _merge_object!(obj, name, delimiter, prefs, type, options={})
1055
1075
  #puts ["\n*****HASH._merge_object", "type: #{type}", "name: #{name}", "self.class: #{self.class}", "new_obj: #{(obj.to_s rescue obj.class)}", "delimiter: #{delimiter}", "prefs: #{prefs}", "options: #{options}"]
1056
- case
1076
+ output = case
1057
1077
  when prefs=='shared'
1058
1078
  _merge_shared!(obj, name, delimiter, prefs, type, options)
1059
1079
  when prefs=='private'
@@ -1063,6 +1083,7 @@ class Hash
1063
1083
  delimit_name = obj._get_attribute(delimiter, options[:shared_variable_name]).to_s.downcase
1064
1084
  #puts "MERGING delimited object with hash: self '#{self.class}' obj '#{obj.class}' name '#{name}' delim '#{delimiter}' delim_name '#{delimit_name}' options '#{options}'"
1065
1085
  self[name] ||= options[:default_class].new
1086
+
1066
1087
  #self[name][delimit_name]=obj
1067
1088
  # This is supposed to handle multiple elements who's delimiter value is the SAME.
1068
1089
  self[name]._merge_delimited_object!(obj, delimit_name)
@@ -1080,9 +1101,11 @@ class Hash
1080
1101
  else
1081
1102
  rslt = self[name] = obj
1082
1103
  _create_accessor(name) if (options[:create_accessors] & ['all','shared','hash']).any?
1083
- #puts ["\nRESULT", self.to_yaml]
1084
1104
  rslt
1085
1105
  end
1106
+ #puts ["\n*****HASH._merge_object! RESULT", self.to_yaml]
1107
+ #puts ["\n*****HASH._merge_object! RESULT PORTALS", (self.portals.to_yaml rescue 'no portals')]
1108
+ output
1086
1109
  end
1087
1110
 
1088
1111
  # def _create_accessors options=[]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ginjo-rfm
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.8
4
+ version: 3.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoff Coffey
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-01-27 00:00:00.000000000 Z
15
+ date: 2015-03-21 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activemodel