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 +4 -4
- data/CHANGELOG.md +20 -10
- data/README.md +1 -1
- data/lib/rfm/VERSION +1 -1
- data/lib/rfm/layout.rb +3 -1
- data/lib/rfm/metadata/datum.rb +2 -2
- data/lib/rfm/utilities/config.rb +1 -0
- data/lib/rfm/utilities/connection.rb +3 -1
- data/lib/rfm/utilities/sax_parser.rb +43 -20
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2a03d23cf578b34173f800b1658fe22465b2736
|
4
|
+
data.tar.gz: 02f0520fabc22fdaf653d02b1afa1b43867e65c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd1ad124d35792b2959dbb3a6f82d0534c303dee8686df59cdf963e255778e843b32cab896437b8e07082d65a2b2f43bd8a27bc4f9a825c15fad892ac0f16773
|
7
|
+
data.tar.gz: dd657b7d1a9fd7c4b85728da57e29fe6d480733bcf7d4ad65f32fbe34e3c6e033148d715198e8c84bb08985f30ef9a0dbce4f0bedcba9d0925b5676c56fad0e2
|
data/CHANGELOG.md
CHANGED
@@ -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
|
-
|
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
|
-
|
216
|
-
|
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
|
-
|
225
|
-
|
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
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
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
|
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
|
|
data/lib/rfm/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.0.
|
1
|
+
3.0.9
|
data/lib/rfm/layout.rb
CHANGED
@@ -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
|
data/lib/rfm/metadata/datum.rb
CHANGED
@@ -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 ['
|
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 ['
|
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
|
data/lib/rfm/utilities/config.rb
CHANGED
@@ -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
|
-
|
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:
|
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:
|
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:
|
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
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
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", "
|
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]
|
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 ["\
|
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
|
-
|
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.
|
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-
|
15
|
+
date: 2015-03-21 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activemodel
|