ginjo-rfm 2.1.1 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +12 -3
- data/README.md +38 -14
- data/lib/rfm/VERSION +1 -2
- data/lib/rfm/utilities/config.rb +3 -3
- metadata +177 -172
- data/lib/rfm/utilities/sax_parser.rb +0 -298
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Ginjo-Rfm 2.1.2
|
4
|
+
|
5
|
+
* Fixed config.rb so that :file_path (to user-defined yml config file) can be specified as a single path string
|
6
|
+
or as an array of path strings.
|
7
|
+
|
8
|
+
## Ginjo-Rfm 2.1.1
|
9
|
+
|
10
|
+
* Bug fixes
|
11
|
+
|
12
|
+
* Specs passing in Ruby 1.8.7, 1.9.2.
|
13
|
+
|
3
14
|
## Ginjo-Rfm 2.1.0
|
4
15
|
|
5
16
|
* Removed `:include_portals` query option in favor of `:ignore_portals`.
|
@@ -15,11 +26,9 @@
|
|
15
26
|
* Added grammar translation layer between xml parser and Rfm, allowing all supported xml grammars to be used with Rfm.
|
16
27
|
This will also streamline changes/additions to Filemaker's xml grammar(s).
|
17
28
|
|
18
|
-
* Added ability to manually import fmprestulset and fmpxmlresult data (from file, variable, etc.).
|
19
|
-
|
20
29
|
* Fixed case statement for ruby 1.9
|
21
30
|
|
22
|
-
* Configuration `:use` option
|
31
|
+
* Configuration `:use` option now works for all Rfm objects that respond to `config`.
|
23
32
|
|
24
33
|
## Ginjo-Rfm 2.0.2
|
25
34
|
|
data/README.md
CHANGED
@@ -15,19 +15,35 @@ Rfm is a Ruby-Filemaker adapter, a Ruby gem that allows scripts and applications
|
|
15
15
|
|
16
16
|
## New in version 2.1
|
17
17
|
|
18
|
-
|
18
|
+
Ginjo-rfm 2.1 has a combination of new features, bug fixes, and a lot of code refactoring.
|
19
19
|
Most api calls remain the same, but a good deal of underlying code has been transformed
|
20
|
-
to support
|
20
|
+
to support and take advantage of the progress of technologies surrounding Ruby.
|
21
21
|
|
22
22
|
* Portals are now included by default.
|
23
23
|
Removed `:include_portals` query option in favor of `:ignore_portals`.
|
24
24
|
Added `:max_portal_rows` query option.
|
25
25
|
* Added field-remapping framework to allow model fields with different names than Filemaker fields.
|
26
|
+
|
27
|
+
class User < Rfm::Base
|
28
|
+
config :field_mapping => {
|
29
|
+
#<filemaker-field-name> => <rfm-field-name>
|
30
|
+
'userName' => 'login',
|
31
|
+
'First Name' => 'first_name',
|
32
|
+
'Last Name' => 'last_name',
|
33
|
+
'IDperson' => 'person_id'
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
User.find(:login=>'bill') # => [{'login' => 'bill', 'first_name' => 'Bill', ...}, ...]
|
38
|
+
|
26
39
|
* Fixed date/time/timestamp translations when writing data to Filemaker.
|
27
40
|
* Detached new Server objects from Factory.servers hash, so wont reuse or stack-up servers.
|
28
41
|
* Added grammar translation layer between xml parser and Rfm, allowing all supported xml grammars to be used with Rfm.
|
29
42
|
This will also streamline changes/additions to Filemaker's xml grammar(s).
|
30
43
|
* Added ability to manually import fmpresultset and fmpxmlresult data (from file, variable, etc.).
|
44
|
+
|
45
|
+
Rfm::Resultset.load_data(file_or_string).
|
46
|
+
|
31
47
|
* Compatibility fixes for ruby 1.9.
|
32
48
|
* Configuration `:use` option now works for all Rfm objects that respond to `config`.
|
33
49
|
|
@@ -179,7 +195,7 @@ Get the total count of all records in the table
|
|
179
195
|
|
180
196
|
MyModel.total_count
|
181
197
|
|
182
|
-
Get the portal names (table-
|
198
|
+
Get the portal names (table-occurrence names) on the current layout
|
183
199
|
|
184
200
|
MyModel.portal_names
|
185
201
|
|
@@ -689,26 +705,30 @@ To delete the record whose recid is 200:
|
|
689
705
|
|
690
706
|
my_layout.delete(200)
|
691
707
|
|
692
|
-
All of these methods return an Rfm::
|
708
|
+
All of these methods return an Rfm::Resultset object (see below), and every one of them takes an optional parameter (the very last one) with additional options. For example, to find just a page full of records, you can do this:
|
693
709
|
|
694
710
|
my_layout.find({:state => "AZ"}, {:max_records => 10, :skip_records => 100})
|
695
711
|
|
696
|
-
For a complete list of the available options, see the "expand_options" method in the Rfm::Server object in the file named
|
712
|
+
For a complete list of the available options, see the "expand_options" method in the Rfm::Server object in the file named server.rb.
|
697
713
|
|
698
|
-
Finally, if filemaker returns an error when executing any of these methods, an error will be raised in your ruby script. There is one exception to this, though. If a find results in no records being found (FileMaker error # 401) I just ignore it and return you a
|
714
|
+
Finally, if filemaker returns an error when executing any of these methods, an error will be raised in your ruby script. There is one exception to this, though. If a find results in no records being found (FileMaker error # 401) I just ignore it and return you a Resultset with zero records in it. If you prefer an error in this case, add :raise_on_401 => true to the options you pass the Rfm::Server when you create it.
|
699
715
|
|
700
716
|
|
701
|
-
###
|
717
|
+
### Resultset and Record Objects
|
702
718
|
|
703
|
-
Any method on the Layout object that returns data will return a
|
719
|
+
Any method on the Layout object that returns data will return a Resultset object. Rfm::Resultset is a subclass of Array, so first and foremost, you can use it like any other array:
|
704
720
|
|
705
721
|
my_result = my_layout.any
|
706
722
|
my_result.size # returns '1'
|
707
|
-
my_result[0] # returns the first record (an Rfm::
|
723
|
+
my_result[0] # returns the first record (an Rfm::Record object)
|
708
724
|
|
709
|
-
The
|
725
|
+
The Resultset object also tells you information about the fields and portals in the result. Resultset#field\_meta and Resultset#portal\_meta are both standard ruby hashes, with strings for keys. The fields hash has Rfm::Metadata::Field objects for values. The portals hash has another hash for its values. This nested hash is the fields on the portal. This would print out all the field names:
|
710
726
|
|
711
|
-
my_result.
|
727
|
+
my_result.field_meta.each { |name, field| puts name }
|
728
|
+
|
729
|
+
Or, as a convenience, you can do this:
|
730
|
+
|
731
|
+
my_result.field_names
|
712
732
|
|
713
733
|
This would print out the tables each portal on the layout is associated with. Below each table name, and indented, it will print the names of all the fields on each portal.
|
714
734
|
|
@@ -717,7 +737,11 @@ This would print out the tables each portal on the layout is associated with. Be
|
|
717
737
|
fields.each { |name, field| puts "\t#{name}"}
|
718
738
|
}
|
719
739
|
|
720
|
-
|
740
|
+
Also as a convenience, you can do this:
|
741
|
+
|
742
|
+
my_result.portal_names
|
743
|
+
|
744
|
+
But most importantly, the Resultset contains record objects. Rfm::Record is a subclass of Hash, so it can be used in many standard ways. This code would print the value in the 'first_name' field in the first record of the Resultset:
|
721
745
|
|
722
746
|
my_record = my_result[0]
|
723
747
|
puts my_record["first_name"]
|
@@ -726,7 +750,7 @@ As a convenience, if your field names are valid ruby method names (ie, they don'
|
|
726
750
|
|
727
751
|
puts my_record.first_name
|
728
752
|
|
729
|
-
Since
|
753
|
+
Since Resultsets are arrays and Records are hashes, you can take advantage of Ruby's wonderful expressiveness. For example, to get a comma-separated list of the full names of all the people in California, you could do this:
|
730
754
|
|
731
755
|
my_layout.find(:state => 'CA').collect {|rec| "#{rec.first_name} #{rec.last_name}"}.join(", ")
|
732
756
|
|
@@ -746,7 +770,7 @@ If you want to detect concurrent modification, you can do this instead:
|
|
746
770
|
|
747
771
|
This version will refuse to update the database and raise an error if the record was modified after it was loaded but before it was saved.
|
748
772
|
|
749
|
-
Record objects also have portals. While the portals in a
|
773
|
+
Record objects also have portals. While the portals in a Resultset tell you about the tables and fields the portals show, the portals in a Record have the actual data. For example, if an Order record has Line Item records, you could do this:
|
750
774
|
|
751
775
|
my_order = order_layout.any[0] # the [0] is important!
|
752
776
|
my_lines = my_order.portals["Line Items"]
|
data/lib/rfm/VERSION
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
2.1.
|
2
|
-
|
1
|
+
2.1.2
|
data/lib/rfm/utilities/config.rb
CHANGED
@@ -124,9 +124,9 @@ module Rfm
|
|
124
124
|
def get_config_file
|
125
125
|
@@config_file_data ||= (
|
126
126
|
config_file_name = @config[:file_name] || (RFM_CONFIG[:file_name] rescue nil) || 'rfm.yml'
|
127
|
-
config_file_paths = [''] | (@config[:file_path] || (RFM_CONFIG[:file_path] rescue nil) || %w( config/ ))
|
128
|
-
config_file_paths.collect do |
|
129
|
-
(YAML.load_file(
|
127
|
+
config_file_paths = [''] | [(@config[:file_path] || (RFM_CONFIG[:file_path] rescue nil) || %w( config/ ))].flatten
|
128
|
+
config_file_paths.collect do |path|
|
129
|
+
(YAML.load_file(File.join(path, config_file_name)) rescue {})
|
130
130
|
end.inject({}){|h,a| h.merge(a)}
|
131
131
|
) || {}
|
132
132
|
end
|
metadata
CHANGED
@@ -1,15 +1,10 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ginjo-rfm
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.1.2
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 1
|
9
|
-
- 1
|
10
|
-
version: 2.1.1
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Geoff Coffey
|
14
9
|
- Mufaddal Khumri
|
15
10
|
- Atsushi Matsuo
|
@@ -18,193 +13,212 @@ authors:
|
|
18
13
|
autorequire:
|
19
14
|
bindir: bin
|
20
15
|
cert_chain: []
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
- !ruby/object:Gem::Dependency
|
16
|
+
date: 2013-03-31 00:00:00.000000000 Z
|
17
|
+
dependencies:
|
18
|
+
- !ruby/object:Gem::Dependency
|
25
19
|
name: activesupport
|
26
|
-
|
27
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
28
21
|
none: false
|
29
|
-
requirements:
|
30
|
-
- -
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
hash: 9
|
33
|
-
segments:
|
34
|
-
- 2
|
35
|
-
- 3
|
36
|
-
- 5
|
22
|
+
requirements:
|
23
|
+
- - ! '>='
|
24
|
+
- !ruby/object:Gem::Version
|
37
25
|
version: 2.3.5
|
38
26
|
type: :runtime
|
39
|
-
version_requirements: *id001
|
40
|
-
- !ruby/object:Gem::Dependency
|
41
|
-
name: activemodel
|
42
27
|
prerelease: false
|
43
|
-
|
28
|
+
version_requirements: !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.3.5
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: activemodel
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
44
37
|
none: false
|
45
|
-
requirements:
|
46
|
-
- -
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
|
49
|
-
segments:
|
50
|
-
- 0
|
51
|
-
version: "0"
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
52
42
|
type: :development
|
53
|
-
version_requirements: *id002
|
54
|
-
- !ruby/object:Gem::Dependency
|
55
|
-
name: rake
|
56
43
|
prerelease: false
|
57
|
-
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rake
|
52
|
+
requirement: !ruby/object:Gem::Requirement
|
58
53
|
none: false
|
59
|
-
requirements:
|
60
|
-
- -
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
|
63
|
-
segments:
|
64
|
-
- 0
|
65
|
-
version: "0"
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
66
58
|
type: :development
|
67
|
-
version_requirements: *id003
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
|
-
name: rdoc
|
70
59
|
prerelease: false
|
71
|
-
|
60
|
+
version_requirements: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: rdoc
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
72
69
|
none: false
|
73
|
-
requirements:
|
74
|
-
- -
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
|
77
|
-
segments:
|
78
|
-
- 0
|
79
|
-
version: "0"
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
80
74
|
type: :development
|
81
|
-
version_requirements: *id004
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: rspec
|
84
75
|
prerelease: false
|
85
|
-
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
77
|
none: false
|
87
|
-
requirements:
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rspec
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
88
87
|
- - ~>
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
hash: 27
|
91
|
-
segments:
|
92
|
-
- 1
|
93
|
-
- 3
|
94
|
-
- 0
|
88
|
+
- !ruby/object:Gem::Version
|
95
89
|
version: 1.3.0
|
96
90
|
type: :development
|
97
|
-
version_requirements: *id005
|
98
|
-
- !ruby/object:Gem::Dependency
|
99
|
-
name: diff-lcs
|
100
91
|
prerelease: false
|
101
|
-
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
102
93
|
none: false
|
103
|
-
requirements:
|
104
|
-
- -
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
94
|
+
requirements:
|
95
|
+
- - ~>
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 1.3.0
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: diff-lcs
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
110
106
|
type: :development
|
111
|
-
version_requirements: *id006
|
112
|
-
- !ruby/object:Gem::Dependency
|
113
|
-
name: yard
|
114
107
|
prerelease: false
|
115
|
-
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
116
109
|
none: false
|
117
|
-
requirements:
|
118
|
-
- -
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
- !ruby/object:Gem::Dependency
|
115
|
+
name: yard
|
116
|
+
requirement: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
124
122
|
type: :development
|
125
|
-
version_requirements: *id007
|
126
|
-
- !ruby/object:Gem::Dependency
|
127
|
-
name: redcarpet
|
128
123
|
prerelease: false
|
129
|
-
|
124
|
+
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
- !ruby/object:Gem::Dependency
|
131
|
+
name: redcarpet
|
132
|
+
requirement: !ruby/object:Gem::Requirement
|
130
133
|
none: false
|
131
|
-
requirements:
|
132
|
-
- -
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
|
135
|
-
segments:
|
136
|
-
- 0
|
137
|
-
version: "0"
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
138
|
type: :development
|
139
|
-
version_requirements: *id008
|
140
|
-
- !ruby/object:Gem::Dependency
|
141
|
-
name: libxml-ruby
|
142
139
|
prerelease: false
|
143
|
-
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: libxml-ruby
|
148
|
+
requirement: !ruby/object:Gem::Requirement
|
144
149
|
none: false
|
145
|
-
requirements:
|
146
|
-
- -
|
147
|
-
- !ruby/object:Gem::Version
|
148
|
-
|
149
|
-
segments:
|
150
|
-
- 0
|
151
|
-
version: "0"
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
152
154
|
type: :development
|
153
|
-
version_requirements: *id009
|
154
|
-
- !ruby/object:Gem::Dependency
|
155
|
-
name: nokogiri
|
156
155
|
prerelease: false
|
157
|
-
|
156
|
+
version_requirements: !ruby/object:Gem::Requirement
|
158
157
|
none: false
|
159
|
-
requirements:
|
160
|
-
- -
|
161
|
-
- !ruby/object:Gem::Version
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
158
|
+
requirements:
|
159
|
+
- - ! '>='
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
- !ruby/object:Gem::Dependency
|
163
|
+
name: nokogiri
|
164
|
+
requirement: !ruby/object:Gem::Requirement
|
165
|
+
none: false
|
166
|
+
requirements:
|
167
|
+
- - ! '>='
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
166
170
|
type: :development
|
167
|
-
version_requirements: *id010
|
168
|
-
- !ruby/object:Gem::Dependency
|
169
|
-
name: hpricot
|
170
171
|
prerelease: false
|
171
|
-
|
172
|
+
version_requirements: !ruby/object:Gem::Requirement
|
172
173
|
none: false
|
173
|
-
requirements:
|
174
|
-
- -
|
175
|
-
- !ruby/object:Gem::Version
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
174
|
+
requirements:
|
175
|
+
- - ! '>='
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
- !ruby/object:Gem::Dependency
|
179
|
+
name: hpricot
|
180
|
+
requirement: !ruby/object:Gem::Requirement
|
181
|
+
none: false
|
182
|
+
requirements:
|
183
|
+
- - ! '>='
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
180
186
|
type: :development
|
181
|
-
version_requirements: *id011
|
182
|
-
- !ruby/object:Gem::Dependency
|
183
|
-
name: ox
|
184
187
|
prerelease: false
|
185
|
-
|
188
|
+
version_requirements: !ruby/object:Gem::Requirement
|
186
189
|
none: false
|
187
|
-
requirements:
|
188
|
-
- -
|
189
|
-
- !ruby/object:Gem::Version
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
190
|
+
requirements:
|
191
|
+
- - ! '>='
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
|
+
- !ruby/object:Gem::Dependency
|
195
|
+
name: ox
|
196
|
+
requirement: !ruby/object:Gem::Requirement
|
197
|
+
none: false
|
198
|
+
requirements:
|
199
|
+
- - ! '>='
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
194
202
|
type: :development
|
195
|
-
|
196
|
-
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
none: false
|
206
|
+
requirements:
|
207
|
+
- - ! '>='
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0'
|
210
|
+
description: Rfm lets your Ruby scripts and Rails applications talk directly to your
|
211
|
+
Filemaker server. Ginjo-rfm includes ActiveModel compatibility, multiple XML parsers,
|
212
|
+
compound Filemaker find requests, and a configuration API.
|
197
213
|
email: http://groups.google.com/group/rfmcommunity
|
198
214
|
executables: []
|
199
|
-
|
200
215
|
extensions: []
|
201
|
-
|
202
|
-
extra_rdoc_files:
|
216
|
+
extra_rdoc_files:
|
203
217
|
- LICENSE
|
204
218
|
- README.md
|
205
219
|
- CHANGELOG.md
|
206
220
|
- lib/rfm/VERSION
|
207
|
-
files:
|
221
|
+
files:
|
208
222
|
- lib/rfm/base.rb
|
209
223
|
- lib/rfm/database.rb
|
210
224
|
- lib/rfm/error.rb
|
@@ -223,7 +237,6 @@ files:
|
|
223
237
|
- lib/rfm/utilities/factory.rb
|
224
238
|
- lib/rfm/utilities/fmpxmlresult.rb
|
225
239
|
- lib/rfm/utilities/fmresultset.rb
|
226
|
-
- lib/rfm/utilities/sax_parser.rb
|
227
240
|
- lib/rfm/utilities/xml_parser.rb
|
228
241
|
- lib/rfm/version.rb
|
229
242
|
- lib/rfm/xml_mini/hpricot.rb
|
@@ -237,41 +250,33 @@ files:
|
|
237
250
|
- CHANGELOG.md
|
238
251
|
homepage: https://rubygems.org/gems/ginjo-rfm
|
239
252
|
licenses: []
|
240
|
-
|
241
253
|
post_install_message:
|
242
|
-
rdoc_options:
|
254
|
+
rdoc_options:
|
243
255
|
- --line-numbers
|
244
256
|
- --main
|
245
257
|
- README.md
|
246
|
-
require_paths:
|
258
|
+
require_paths:
|
247
259
|
- lib
|
248
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
260
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
249
261
|
none: false
|
250
|
-
requirements:
|
251
|
-
- -
|
252
|
-
- !ruby/object:Gem::Version
|
253
|
-
|
254
|
-
segments:
|
262
|
+
requirements:
|
263
|
+
- - ! '>='
|
264
|
+
- !ruby/object:Gem::Version
|
265
|
+
version: '0'
|
266
|
+
segments:
|
255
267
|
- 0
|
256
|
-
|
257
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
268
|
+
hash: -510283232379124376
|
269
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
258
270
|
none: false
|
259
|
-
requirements:
|
260
|
-
- -
|
261
|
-
- !ruby/object:Gem::Version
|
262
|
-
hash: 25
|
263
|
-
segments:
|
264
|
-
- 1
|
265
|
-
- 3
|
266
|
-
- 1
|
271
|
+
requirements:
|
272
|
+
- - ! '>'
|
273
|
+
- !ruby/object:Gem::Version
|
267
274
|
version: 1.3.1
|
268
275
|
requirements: []
|
269
|
-
|
270
276
|
rubyforge_project:
|
271
277
|
rubygems_version: 1.8.25
|
272
278
|
signing_key:
|
273
279
|
specification_version: 3
|
274
280
|
summary: Ruby to Filemaker adapter
|
275
281
|
test_files: []
|
276
|
-
|
277
282
|
has_rdoc:
|
@@ -1,298 +0,0 @@
|
|
1
|
-
# From https://github.com/ohler55/ox
|
2
|
-
#gem 'ox', '1.8.5'
|
3
|
-
require 'stringio'
|
4
|
-
require 'ox'
|
5
|
-
require 'delegate'
|
6
|
-
require 'yaml'
|
7
|
-
require 'rfm'
|
8
|
-
|
9
|
-
|
10
|
-
##### CORE PATCHES #####
|
11
|
-
|
12
|
-
module Saxable
|
13
|
-
|
14
|
-
# Default callbacks for Saxable objects.
|
15
|
-
def parent; @parent || self end
|
16
|
-
def start_el(name, attributes); self end
|
17
|
-
def attribute(name,value); (self[name]=value) rescue nil end
|
18
|
-
def end_el(value); true end
|
19
|
-
|
20
|
-
def self.included(base)
|
21
|
-
attr_accessor :parent, :_new_element, :_new_element_name, :_new_element_attributes
|
22
|
-
|
23
|
-
class << base
|
24
|
-
|
25
|
-
attr_reader :_start_el_lambdas
|
26
|
-
# This is a class method that allows shortcut config, kinda like 'before_filter'.
|
27
|
-
# Helper shortcut method to be used in Saxable method at class level.
|
28
|
-
# When this loads, it will define a more elaborate hidden start_el operation.
|
29
|
-
# Lambdas needed to allow multiple start_el calls at Saxable object class level.
|
30
|
-
def start_el(el, kls)
|
31
|
-
@_start_el_lambdas ||= []
|
32
|
-
|
33
|
-
# Disable this to use the non-lambda version.
|
34
|
-
@_start_el_lambdas << lambda do |slf|
|
35
|
-
name = slf._new_element_name
|
36
|
-
if (name.match(el) if el.is_a? Regexp) || name == el
|
37
|
-
sub = Object.const_get(kls.to_s).new rescue kls.new
|
38
|
-
sub.parent = slf
|
39
|
-
sub.merge!(slf._new_element_attributes) rescue nil
|
40
|
-
slf._new_element = sub
|
41
|
-
yield(slf) if block_given?
|
42
|
-
return slf._new_element
|
43
|
-
else
|
44
|
-
#return slf
|
45
|
-
return nil
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# This is the actual instance-level start_el method.
|
50
|
-
# The lambda version will call multiple lambdas,
|
51
|
-
# whereas the single version will only call once.
|
52
|
-
define_method :start_el do |name, attributes|
|
53
|
-
# This is for the lambda version.
|
54
|
-
self._new_element_name = name
|
55
|
-
self._new_element_attributes = attributes
|
56
|
-
#
|
57
|
-
# This is the non-lambda one-shot only version.
|
58
|
-
#
|
59
|
-
# if (name.match(el) if el.is_a? Regexp) || name == el
|
60
|
-
# self._new_element = Object.const_get(kls.to_s).new
|
61
|
-
# self._new_element.parent = self
|
62
|
-
# self._new_element_name = name
|
63
|
-
# yield(self) if block_given?
|
64
|
-
# return self._new_element
|
65
|
-
# else
|
66
|
-
# return self
|
67
|
-
# #return nil
|
68
|
-
# end
|
69
|
-
#
|
70
|
-
# This is the lambda version
|
71
|
-
#
|
72
|
-
begin
|
73
|
-
result = (self.class.instance_variable_get(:@_start_el_lambdas).compact.each{|e| @sub = e.call(self); break if @sub}; @sub || self)
|
74
|
-
#self.class.instance_variable_get(:@_start_el).last.call(self, parent, name) rescue nil || self
|
75
|
-
#puts "Successfully processed lambdas"
|
76
|
-
result
|
77
|
-
rescue
|
78
|
-
#puts "Errors processing lambdas: #{$!}"
|
79
|
-
self
|
80
|
-
end
|
81
|
-
#
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def end_el(el)
|
86
|
-
define_method :end_el do |name|
|
87
|
-
if (name.match(el) if el.is_a? Regexp) || name == el
|
88
|
-
self._new_element_name = name
|
89
|
-
yield(self) if block_given?
|
90
|
-
return true
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def element(*args)
|
96
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
97
|
-
start_el args[0].to_s, options[:class] do |slf|
|
98
|
-
slf.is_a? Hash
|
99
|
-
slf[slf._new_element_name] = slf._new_element
|
100
|
-
elsif slf.is_a? Array
|
101
|
-
slf << slf._new_element
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
end # Saxable
|
110
|
-
|
111
|
-
class Hash
|
112
|
-
include Saxable
|
113
|
-
end
|
114
|
-
class Array
|
115
|
-
include Saxable
|
116
|
-
end
|
117
|
-
|
118
|
-
|
119
|
-
module SaxHandler
|
120
|
-
|
121
|
-
def self.included(base)
|
122
|
-
def base.build(io, initial_object)
|
123
|
-
handler = new(initial_object)
|
124
|
-
handler.run_parser(io)
|
125
|
-
handler.cursor
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def initialize(initial_object)
|
130
|
-
init_element_buffer
|
131
|
-
initial_object.parent = set_cursor initial_object
|
132
|
-
end
|
133
|
-
|
134
|
-
def cursor
|
135
|
-
@cursor
|
136
|
-
end
|
137
|
-
|
138
|
-
def set_cursor(obj)
|
139
|
-
@cursor = obj
|
140
|
-
end
|
141
|
-
|
142
|
-
def init_element_buffer
|
143
|
-
@element_buffer = {:name=>nil, :attr=>{}}
|
144
|
-
end
|
145
|
-
|
146
|
-
def send_element_buffer
|
147
|
-
if element_buffer?
|
148
|
-
set_cursor cursor.start_el(@element_buffer[:name], @element_buffer[:attr])
|
149
|
-
init_element_buffer
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def element_buffer?
|
154
|
-
@element_buffer[:name] && !@element_buffer[:name].empty?
|
155
|
-
end
|
156
|
-
|
157
|
-
# Add a node to an existing element.
|
158
|
-
def _start_element(name, attributes=nil)
|
159
|
-
send_element_buffer
|
160
|
-
if attributes.nil?
|
161
|
-
@element_buffer = {:name=>name, :attr=>{}}
|
162
|
-
else
|
163
|
-
set_cursor cursor.start_el(name, attributes)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
# Add attribute to existing element.
|
168
|
-
def _attribute(name, value)
|
169
|
-
@element_buffer[:attr].merge!({name=>value})
|
170
|
-
#cursor.attribute(name,value)
|
171
|
-
end
|
172
|
-
|
173
|
-
# Add 'content' attribute to existing element.
|
174
|
-
def _text(value)
|
175
|
-
if !element_buffer?
|
176
|
-
cursor.attribute('content', value)
|
177
|
-
else
|
178
|
-
@element_buffer[:attr].merge!({'content'=>value})
|
179
|
-
send_element_buffer
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
# Close out an existing element.
|
184
|
-
def _end_element(value)
|
185
|
-
send_element_buffer
|
186
|
-
cursor.end_el(value) and set_cursor cursor.parent
|
187
|
-
end
|
188
|
-
|
189
|
-
end # SaxHandler
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
##### XML PARSERS - SAX HANDLERS #####
|
194
|
-
|
195
|
-
class OxFmpSax < ::Ox::Sax
|
196
|
-
|
197
|
-
include SaxHandler
|
198
|
-
|
199
|
-
def run_parser(io)
|
200
|
-
#Ox.sax_parse(self, io)
|
201
|
-
File.open(io){|f| Ox.sax_parse self, f}
|
202
|
-
end
|
203
|
-
|
204
|
-
def start_element(name); _start_element(name.to_s.downcase); end
|
205
|
-
def end_element(name); _end_element(name.to_s.downcase); end
|
206
|
-
def attr(name, value); _attribute(name.to_s.downcase, value); end
|
207
|
-
def text(value); _text(value); end
|
208
|
-
|
209
|
-
end # OxFmpSax
|
210
|
-
|
211
|
-
|
212
|
-
class FmResultset < Hash
|
213
|
-
start_el 'datasource', :Datasource do |slf|
|
214
|
-
slf[slf._new_element_name] = slf._new_element
|
215
|
-
end
|
216
|
-
start_el 'resultset', :Resultset do |slf|
|
217
|
-
slf[slf._new_element_name] = slf._new_element
|
218
|
-
end
|
219
|
-
start_el 'metadata', :Metadata do |slf|
|
220
|
-
slf[slf._new_element_name] = slf._new_element
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
class Datasource < Hash
|
225
|
-
start_el /.*/i, :Hash
|
226
|
-
end
|
227
|
-
|
228
|
-
class Metadata < Array
|
229
|
-
start_el 'field-definition', :Hash do |slf|
|
230
|
-
slf << slf._new_element
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
class Resultset < Array
|
235
|
-
start_el 'record', :Record do |slf|
|
236
|
-
slf << slf._new_element
|
237
|
-
end
|
238
|
-
# Enable this to kill attribute parsing for this object.
|
239
|
-
#def attribute(*args); end
|
240
|
-
end
|
241
|
-
|
242
|
-
class Record < Hash
|
243
|
-
start_el 'field', :Field
|
244
|
-
end
|
245
|
-
|
246
|
-
class Field < Hash
|
247
|
-
end_el 'field' do |slf|
|
248
|
-
slf.parent[slf['name']] = slf['content']
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
# This gives a generic tree structure.
|
253
|
-
class Hash
|
254
|
-
start_el /.*/i, :Hash do |slf|
|
255
|
-
name, sub = slf._new_element_name, slf._new_element
|
256
|
-
|
257
|
-
if slf[name].is_a? Array
|
258
|
-
slf[name] << sub
|
259
|
-
elsif slf.has_key? name
|
260
|
-
tmp = slf[name]
|
261
|
-
slf[name] = [tmp]
|
262
|
-
slf[name] << sub
|
263
|
-
else
|
264
|
-
slf[name] = sub
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
end_el /.*/i do |slf|
|
269
|
-
parent, name = slf.parent, slf._new_element_name
|
270
|
-
#parent[name]=nil if slf.empty? # Use nil for empty nodes.
|
271
|
-
#parent.delete(name) if slf.empty? # Delete empty nodes.
|
272
|
-
parent[name] = slf.values[0] unless slf.size > 1 or parent.size > 2 # Reduce unnecessary nodes.
|
273
|
-
end
|
274
|
-
|
275
|
-
end
|
276
|
-
|
277
|
-
|
278
|
-
##### DATA #####
|
279
|
-
|
280
|
-
FM = 'local_testing/resultset.xml'
|
281
|
-
FMP = 'local_testing/resultset_with_portals.xml'
|
282
|
-
XML = 'local_testing/data_fmpxmlresult.xml'
|
283
|
-
XMP = 'local_testing/data_with_portals_fmpxmlresult.xml'
|
284
|
-
LAY = 'local_testing/layout.xml'
|
285
|
-
XMD = 'local_testing/db_fmpxmlresult.xml'
|
286
|
-
FMB = 'local_testing/resultset_with_bad_data.xml'
|
287
|
-
SP = 'local_testing/SplashLayout.xml'
|
288
|
-
|
289
|
-
S = StringIO.new(%{
|
290
|
-
<top name="top01">
|
291
|
-
<middle name="middle01" />
|
292
|
-
<middle name="middle02">
|
293
|
-
<bottom name="bottom01">bottom-text</bottom>
|
294
|
-
</middle>
|
295
|
-
<middle name="middle03">middle03-text</middle>
|
296
|
-
</top>
|
297
|
-
})
|
298
|
-
|