ginjo-rfm 1.4.3 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +16 -44
- data/lib/rfm.rb +4 -10
- data/lib/rfm/VERSION +1 -1
- data/lib/rfm/layout.rb +3 -13
- data/lib/rfm/metadata/value_list_item.rb +29 -26
- data/lib/rfm/record.rb +4 -4
- data/lib/rfm/resultset.rb +0 -1
- data/lib/rfm/server.rb +2 -2
- data/lib/rfm/version.rb +1 -3
- metadata +77 -5
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# ginjo-rfm
|
2
2
|
|
3
|
-
Rfm is a Ruby/Filemaker adapter - a ruby gem that allows scripts and applications to exchange commands and data with Filemaker Pro using Filemaker's XML interface. Ginjo-rfm picks up from the lardawge-rfm gem and continues to refine code and fix bugs. It also adds minor enhancements like server timeout and value-list alternate display. To read more about Rfm, see the info at [Sixfriedrice](http://sixfriedrice.com/wp/products/rfm/), or check out the [RDoc](http://
|
3
|
+
Rfm is a Ruby/Filemaker adapter - a ruby gem that allows scripts and applications to exchange commands and data with Filemaker Pro using Filemaker's XML interface. Ginjo-rfm picks up from the lardawge-rfm gem and continues to refine code and fix bugs. It also adds minor enhancements like server timeout and value-list alternate display. To read more about Rfm, see the info at [Sixfriedrice](http://sixfriedrice.com/wp/products/rfm/), or check out the [RDoc](http://rubydoc.info/github/ginjo/rfm/master/frames).
|
4
4
|
|
5
5
|
Rfm was primarily designed by Six Fried Rice co-founder Geoff Coffey.
|
6
6
|
|
@@ -9,15 +9,18 @@ Other lead contributors:
|
|
9
9
|
* Mufaddal Khumri helped architect Rfm in the most ruby-like way possible. He also contributed the outstanding error handling code and a comprehensive hierarchy of error classes.
|
10
10
|
* Atsushi Matsuo was an early Rfm tester, and provided outstanding feedback, critical code fixes, and a lot of web exposure.
|
11
11
|
* Jesse Antunes helped ensure that Rfm is stable and functional.
|
12
|
-
* Larry Sprock added ssl support
|
12
|
+
* Larry Sprock added ssl support, switched the xml parser to a much faster Nokogiri, added the rspec testing framework, and refactored the code to pave way for future development.
|
13
13
|
|
14
|
-
Documentation
|
14
|
+
Documentation & Links
|
15
15
|
|
16
|
-
*
|
17
|
-
*
|
18
|
-
*
|
16
|
+
* Ginjo-rfm homepage: <https://rubygems.org/gems/ginjo-rfm>
|
17
|
+
* Original homepage: <http://sixfriedrice.com/wp/products/rfm/>
|
18
|
+
* Rdoc location: <http://rubydoc.info/github/ginjo/rfm/frames>
|
19
|
+
* Discussion: <http://groups.google.com/group/rfmcommunity>
|
20
|
+
* Ginjo-rfm <https://github.com/ginjo/rfm>
|
21
|
+
* Lardawge-rfm <https://github.com/lardawge/rfm>
|
19
22
|
|
20
|
-
|
23
|
+
Partial list of features added since rfm 1.0.0.
|
21
24
|
|
22
25
|
* SSL support
|
23
26
|
* Nokogiri xml parser
|
@@ -29,6 +32,7 @@ Partial roadmap to the future
|
|
29
32
|
|
30
33
|
* ActiveModel compatibility
|
31
34
|
* Alternative XML parsers
|
35
|
+
* Complex Filemaker queries
|
32
36
|
* More tests
|
33
37
|
|
34
38
|
|
@@ -43,22 +47,19 @@ Terminal:
|
|
43
47
|
|
44
48
|
Once the gem is installed, you can use rfm in your ruby scripts by requiring it:
|
45
49
|
|
46
|
-
#ruby
|
47
50
|
require 'rubygems'
|
48
51
|
require 'rfm'
|
49
52
|
|
50
|
-
### In Rails >= 3.0
|
53
|
+
### In Rails >= 3.0, or any project using Bundler
|
51
54
|
|
52
55
|
In the Gemfile:
|
53
56
|
|
54
|
-
#ruby
|
55
57
|
gem 'ginjo-rfm'
|
56
58
|
|
57
59
|
### Edge - in an upcoming version of ginjo-rfm
|
58
60
|
|
59
61
|
ActiveModel support.
|
60
62
|
|
61
|
-
#ruby
|
62
63
|
class Account < Rfm::Base
|
63
64
|
config :layout=>'account_xml'
|
64
65
|
before_create :encrypt_password
|
@@ -71,12 +72,12 @@ ActiveModel support.
|
|
71
72
|
@account.email = 'my@email.com'
|
72
73
|
@account.save!
|
73
74
|
|
74
|
-
Multiple backend xml parsers.
|
75
|
+
Multiple backend xml parsers.
|
75
76
|
|
76
|
-
|
77
|
-
# Backend options => :libxml, :libxmlsax, :nokogiri, :nokogirisax, :rexml
|
77
|
+
Rfm::Server.new(:backend => :nokogiri)
|
78
|
+
# Backend options => :libxml, :libxmlsax, :nokogiri, :nokogirisax, :hpricot, :rexml
|
78
79
|
|
79
|
-
Try
|
80
|
+
Try out these unreleased features in the edge branch.
|
80
81
|
|
81
82
|
#gemfile
|
82
83
|
gem 'ginjo-rfm', :git=>'git://github.com/ginjo/rfm.git', :branch=>'edge'
|
@@ -86,7 +87,6 @@ Try it out:
|
|
86
87
|
IMPORTANT:SSL and Certificate verification are on by default. Please see Server#new in rdocs for explanation and setup.
|
87
88
|
You connect with the Rfm::Server object. This little buddy will be your window into FileMaker data.
|
88
89
|
|
89
|
-
#ruby
|
90
90
|
require 'rfm'
|
91
91
|
|
92
92
|
my_server = Rfm::Server.new(
|
@@ -98,7 +98,6 @@ You connect with the Rfm::Server object. This little buddy will be your window i
|
|
98
98
|
|
99
99
|
if your web publishing engine runs on a port other than 80, you can provide the port number as well:
|
100
100
|
|
101
|
-
#ruby
|
102
101
|
my_server = Rfm::Server.new(
|
103
102
|
:host => 'myservername',
|
104
103
|
:account_name => 'user',
|
@@ -112,44 +111,36 @@ if your web publishing engine runs on a port other than 80, you can provide the
|
|
112
111
|
|
113
112
|
All access to data in FileMaker's XML interface is done through layouts, and layouts live in databases. The Rfm::Server object has a collection of databases called 'db'. So to get ahold of a database called "My Database", you can do this:
|
114
113
|
|
115
|
-
#ruby
|
116
114
|
my_db = my_server.db["My Database"]
|
117
115
|
|
118
116
|
As a convenience, you can do this too:
|
119
117
|
|
120
|
-
#ruby
|
121
118
|
my_db = my_server["My Database"]
|
122
119
|
|
123
120
|
Finally, if you want to introspect the server and find out what databases are available, you can do this:
|
124
121
|
|
125
|
-
#ruby
|
126
122
|
all_dbs = my_server.db.all
|
127
123
|
|
128
124
|
In any case, you get back Rfm::Database objects. A database object in turn has a property called "layout":
|
129
125
|
|
130
|
-
#ruby
|
131
126
|
my_layout = my_db.layout["My Layout"]
|
132
127
|
|
133
128
|
Again, for convenience:
|
134
129
|
|
135
|
-
#ruby
|
136
130
|
my_layout = my_db["My Layout"]
|
137
131
|
|
138
132
|
And to get them all:
|
139
133
|
|
140
|
-
#ruby
|
141
134
|
all_layouts = my_db.layout.all
|
142
135
|
|
143
136
|
Bringing it all together, you can do this to go straight from a server to a specific layout:
|
144
137
|
|
145
|
-
#ruby
|
146
138
|
my_layout = my_server["My Database"]["My Layout"]
|
147
139
|
|
148
140
|
## Working with Layouts
|
149
141
|
|
150
142
|
Once you have a layout object, you can start doing some real work. To get every record from the layout:
|
151
143
|
|
152
|
-
#ruby
|
153
144
|
my_layout.all # be careful with this
|
154
145
|
|
155
146
|
To get a random record:
|
@@ -159,12 +150,10 @@ To get a random record:
|
|
159
150
|
|
160
151
|
To find every record with "Arizona" in the "State" field:
|
161
152
|
|
162
|
-
#ruby
|
163
153
|
my_layout.find({"State" => "Arizona"})
|
164
154
|
|
165
155
|
To add a new record with my personal info:
|
166
156
|
|
167
|
-
#ruby
|
168
157
|
my_layout.create({
|
169
158
|
:first_name => "Geoff",
|
170
159
|
:last_name => "Coffey",
|
@@ -175,19 +164,16 @@ Notice that in this case I used symbols instead of strings for the hash keys. Th
|
|
175
164
|
|
176
165
|
To edit the record whos recid (filemaker internal record id) is 200:
|
177
166
|
|
178
|
-
#ruby
|
179
167
|
my_layout.edit(200, {:first_name => 'Mamie'})
|
180
168
|
|
181
169
|
Note: See the "Record Objects" section below for more on editing records.
|
182
170
|
|
183
171
|
To delete the record whose recid is 200:
|
184
172
|
|
185
|
-
#ruby
|
186
173
|
my_layout.delete(200)
|
187
174
|
|
188
175
|
All of these methods return an Rfm::Result::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:
|
189
176
|
|
190
|
-
#ruby
|
191
177
|
my_layout.find({:state => "AZ"}, {:max_records => 10, :skip_records => 100})
|
192
178
|
|
193
179
|
For a complete list of the available options, see the "expand_options" method in the Rfm::Server object in the file named rfm_command.rb.
|
@@ -199,19 +185,16 @@ Finally, if filemaker returns an error when executing any of these methods, an e
|
|
199
185
|
|
200
186
|
Any method on the Layout object that returns data will return a ResultSet object. Rfm::Result::ResultSet is a subclass of Array, so first and foremost, you can use it like any other array:
|
201
187
|
|
202
|
-
#ruby
|
203
188
|
my_result = my_layout.any
|
204
189
|
my_result.size # returns '1'
|
205
190
|
my_result[0] # returns the first record (an Rfm::Result::Record object)
|
206
191
|
|
207
192
|
The ResultSet object also tells you information about the fields and portals in the result. ResultSet#fields and ResultSet#portals are both standard ruby hashes, with strings for keys. The fields hash has Rfm::Result::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:
|
208
193
|
|
209
|
-
#ruby
|
210
194
|
my_result.fields.each { |name, field| puts name }
|
211
195
|
|
212
196
|
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.
|
213
197
|
|
214
|
-
#ruby
|
215
198
|
my_result.portals.each { |table, fields|
|
216
199
|
puts "table: #{table}"
|
217
200
|
fields.each { |name, field| puts "\t#{name}"}
|
@@ -219,42 +202,35 @@ This would print out the tables each portal on the layout is associated with. Be
|
|
219
202
|
|
220
203
|
But most importantly, the ResultSet contains record objects. Rfm::Result::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:
|
221
204
|
|
222
|
-
#ruby
|
223
205
|
my_record = my_result[0]
|
224
206
|
puts my_record["first_name"]
|
225
207
|
|
226
208
|
As a convenience, if your field names are valid ruby method names (ie, they don't have spaces or odd punctuation in them), you can do this instead:
|
227
209
|
|
228
|
-
#ruby
|
229
210
|
puts my_record.first_name
|
230
211
|
|
231
212
|
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:
|
232
213
|
|
233
|
-
#ruby
|
234
214
|
my_layout.find(:state => 'CA').collect {|rec| "#{rec.first_name} #{rec.last_name}"}.join(", ")
|
235
215
|
|
236
216
|
Record objects can also be edited:
|
237
217
|
|
238
|
-
#ruby
|
239
218
|
my_record.first_name = 'Isabel'
|
240
219
|
|
241
220
|
Once you have made a series of edits, you can save them back to the database like this:
|
242
221
|
|
243
|
-
#ruby
|
244
222
|
my_record.save
|
245
223
|
|
246
224
|
The save operation causes the record to be reloaded from the database, so any changes that have been made outside your script will also be picked up after the save.
|
247
225
|
|
248
226
|
If you want to detect concurrent modification, you can do this instead:
|
249
227
|
|
250
|
-
#ruby
|
251
228
|
my_record.save_if_not_modified
|
252
229
|
|
253
230
|
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.
|
254
231
|
|
255
232
|
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:
|
256
233
|
|
257
|
-
#ruby
|
258
234
|
my_order = order_layout.any[0] # the [0] is important!
|
259
235
|
my_lines = my_order.portals["Line Items"]
|
260
236
|
|
@@ -262,13 +238,11 @@ At the end of the previous block of code, my_lines is an array of Record objects
|
|
262
238
|
|
263
239
|
NOTE: Fields on a portal have the table name and the "::" stripped off of their names if they belong to the table the portal is tied to. In other words, if our "Line Items" portal includes a quantity field and a price field, you would do this:
|
264
240
|
|
265
|
-
#ruby
|
266
241
|
my_lines[0]["Quantity"]
|
267
242
|
my_lines[0]["Price"]
|
268
243
|
|
269
244
|
You would NOT do this:
|
270
245
|
|
271
|
-
#ruby
|
272
246
|
my_lines[0]["Line Items::Quantity"]
|
273
247
|
my_lines[0]["Line Items::Quantity"]
|
274
248
|
|
@@ -276,7 +250,6 @@ My feeling is that the table name is redundant and cumbersome if it is the same
|
|
276
250
|
|
277
251
|
Again, you can string things together with Ruby. This will calculate the total dollar amount of the order:
|
278
252
|
|
279
|
-
#ruby
|
280
253
|
total = 0.0
|
281
254
|
my_order.portals["Line Items"].each {|line| total += line.quantity * line.price}
|
282
255
|
|
@@ -315,7 +288,6 @@ When this is 'true' your script will dump the actual response it got from FileMa
|
|
315
288
|
|
316
289
|
So, for an annoying, but detailed load of output, make a connection like this:
|
317
290
|
|
318
|
-
#ruby
|
319
291
|
my_server => Rfm::Server.new(
|
320
292
|
:host => 'myservername',
|
321
293
|
:account_name => 'user',
|
data/lib/rfm.rb
CHANGED
@@ -1,13 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
# require path + '/rfm/utilities/factory'
|
6
|
-
# require path + '/rfm/version.rb'
|
7
|
-
|
8
|
-
Rfm = Module.new unless defined? Rfm
|
9
|
-
Rfm::PATH = File.expand_path(File.dirname(__FILE__))
|
10
|
-
$LOAD_PATH.unshift(Rfm::PATH) unless $LOAD_PATH.include?(Rfm::PATH)
|
1
|
+
module Rfm
|
2
|
+
PATH = File.expand_path(File.dirname(__FILE__))
|
3
|
+
$LOAD_PATH.unshift(PATH) unless $LOAD_PATH.include?(PATH)
|
4
|
+
end
|
11
5
|
|
12
6
|
require 'rfm/utilities/case_insensitive_hash'
|
13
7
|
require 'rfm/utilities/factory'
|
data/lib/rfm/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.4.
|
1
|
+
1.4.4
|
data/lib/rfm/layout.rb
CHANGED
@@ -221,46 +221,36 @@ module Rfm
|
|
221
221
|
@value_lists
|
222
222
|
end
|
223
223
|
|
224
|
-
|
224
|
+
private
|
225
225
|
|
226
226
|
def load
|
227
227
|
#require 'rexml/document'
|
228
228
|
require 'nokogiri'
|
229
229
|
|
230
230
|
@loaded = true
|
231
|
-
#fmpxmllayout = @db.server.load_layout(self).body
|
232
231
|
fmpxmllayout = @db.server.load_layout(self)
|
233
|
-
#doc = REXML::Document.new(fmpxmllayout)
|
234
232
|
doc = Nokogiri::XML(fmpxmllayout)
|
235
|
-
#root = doc.root
|
236
233
|
|
237
234
|
# check for errors
|
238
|
-
#error = root.elements['ERRORCODE'].text.to_i
|
239
235
|
error = doc.xpath('//ERRORCODE').children[0].to_s.to_i
|
240
236
|
raise Rfm::Error::FileMakerError.getError(error) if error != 0
|
241
237
|
|
242
238
|
# process valuelists
|
243
|
-
if doc.xpath('//VALUELIST').size > 0
|
244
|
-
#root.elements['VALUELISTS'].each_element('VALUELIST') { |valuelist|
|
239
|
+
if doc.xpath('//VALUELIST').size > 0
|
245
240
|
doc.xpath('//VALUELIST').each {|valuelist|
|
246
241
|
name = valuelist['NAME']
|
247
|
-
#@value_lists[name] = valuelist.elements.collect {|e| e.text}
|
248
242
|
@value_lists[name] = valuelist.children.collect{|value|
|
249
243
|
Rfm::Metadata::ValueListItem.new(value.children[0].to_s, value['DISPLAY'], name)
|
250
|
-
}
|
244
|
+
} rescue []
|
251
245
|
}
|
252
246
|
@value_lists.freeze
|
253
247
|
end
|
254
248
|
|
255
249
|
# process field controls
|
256
|
-
#root.elements['LAYOUT'].each_element('FIELD') { |field|
|
257
250
|
doc.xpath('//FIELD').each {|field|
|
258
|
-
#name = field.attributes['NAME']
|
259
251
|
name = field['NAME']
|
260
252
|
style_xml = field.children[0]
|
261
|
-
#style = field.elements['STYLE'].attributes['TYPE']
|
262
253
|
style = style_xml['TYPE']
|
263
|
-
#value_list_name = field.elements['STYLE'].attributes['VALUELIST']
|
264
254
|
value_list_name = style_xml['VALUELIST']
|
265
255
|
value_list = @value_lists[value_list_name] if value_list_name != ''
|
266
256
|
field_control = Rfm::Metadata::FieldControl.new(name, style, value_list_name, value_list)
|
@@ -1,27 +1,30 @@
|
|
1
1
|
module Rfm
|
2
|
-
module Metadata
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
2
|
+
module Metadata
|
3
|
+
|
4
|
+
# The ValueListItem object represents an item in a Filemaker value list.
|
5
|
+
# ValueListItem is subclassed from String, so you can use it just like
|
6
|
+
# a string. It does have three additional methods to help separate Filemaker *value*
|
7
|
+
# vs *display* items.
|
8
|
+
#
|
9
|
+
# Getting values vs display items:
|
10
|
+
#
|
11
|
+
# * *#value* the value list item value
|
12
|
+
#
|
13
|
+
# * *#display* is the value list item display. It could be the same
|
14
|
+
# as +value+, or it could be the "second field", if that option is checked in Filemaker
|
15
|
+
#
|
16
|
+
# * *#value_list_name* is the name of the parent value list, if any
|
17
|
+
class ValueListItem < String
|
18
|
+
attr_reader :value, :display, :value_list_name
|
19
|
+
|
20
|
+
def initialize(value, display, value_list_name)
|
21
|
+
@value_list_name = value_list_name
|
22
|
+
@value = value.to_s
|
23
|
+
@display = display.to_s
|
24
|
+
self.replace @value
|
25
|
+
end
|
26
|
+
|
27
|
+
end # ValueListItem
|
28
|
+
|
29
|
+
end # Metadata
|
30
|
+
end # Rfm
|
data/lib/rfm/record.rb
CHANGED
@@ -167,6 +167,7 @@ module Rfm
|
|
167
167
|
self.merge!(@layout.edit(self.record_id, @mods)[0]) if @mods.size > 0
|
168
168
|
@mods.clear
|
169
169
|
end
|
170
|
+
|
170
171
|
|
171
172
|
# Like Record::save, except it fails (and raises an error) if the underlying record in FileMaker was
|
172
173
|
# modified after the record was fetched but before it was saved. In other words, prevents you from
|
@@ -190,7 +191,7 @@ module Rfm
|
|
190
191
|
# When you do, the change is noted, but *the data is not updated in FileMaker*. You must call
|
191
192
|
# Record::save or Record::save_if_not_modified to actually save the data.
|
192
193
|
def []=(name, value)
|
193
|
-
name = name.to_s
|
194
|
+
name = name.to_s.downcase
|
194
195
|
return super unless @loaded
|
195
196
|
raise Rfm::ParameterError,
|
196
197
|
"You attempted to modify a field that does not exist in the current Filemaker layout." unless self.key?(name)
|
@@ -211,9 +212,9 @@ module Rfm
|
|
211
212
|
private
|
212
213
|
|
213
214
|
def read_attribute(key)
|
214
|
-
|
215
|
+
key_string = key.to_s.downcase
|
215
216
|
raise NoMethodError,
|
216
|
-
"#{
|
217
|
+
"#{key_string} does not exists as a field in the current Filemaker layout." unless (!@layout or self.key?(key_string)) #!self.keys.grep(/#{key_string}/i).empty?
|
217
218
|
self._old_hash_reader(key).to_s.empty? ? nil : self._old_hash_reader(key) if self._old_hash_reader(key)
|
218
219
|
end
|
219
220
|
|
@@ -222,7 +223,6 @@ module Rfm
|
|
222
223
|
return read_attribute(method) if self.key?(method)
|
223
224
|
|
224
225
|
if method =~ /(=)$/ && self.key?($`)
|
225
|
-
#return @mods[$`] = attrs.first
|
226
226
|
return self[$`] = attrs.first
|
227
227
|
end
|
228
228
|
super
|
data/lib/rfm/resultset.rb
CHANGED
data/lib/rfm/server.rb
CHANGED
@@ -138,7 +138,7 @@ module Rfm
|
|
138
138
|
# ignores FileMaker's 401 error (no records found) and returns an empty record set instead; if you
|
139
139
|
# prefer a raised error when a find produces no errors, set this option to +true+
|
140
140
|
#
|
141
|
-
#SSL Options (SSL AND CERTIFICATE VERIFICATION ARE ON BY DEFAULT):
|
141
|
+
# ===SSL Options (SSL AND CERTIFICATE VERIFICATION ARE ON BY DEFAULT):
|
142
142
|
#
|
143
143
|
# * *ssl* +false+ if you want to turn SSL (HTTPS) off when connecting to connect to FileMaker (default is +true+)
|
144
144
|
#
|
@@ -154,7 +154,7 @@ module Rfm
|
|
154
154
|
#
|
155
155
|
# * *root_cert_path* path to cert file. (defaults to '/' if no path given)
|
156
156
|
#
|
157
|
-
#Configuration Examples:
|
157
|
+
# ===Configuration Examples:
|
158
158
|
#
|
159
159
|
# Example to turn off SSL:
|
160
160
|
#
|
data/lib/rfm/version.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Rfm
|
2
|
-
|
3
2
|
VERSION_DEFAULT = 'none'
|
4
|
-
VERSION = File.read(PATH + '/rfm/VERSION').first.
|
5
|
-
|
3
|
+
VERSION = File.read(PATH + '/rfm/VERSION').lines.first.chomp rescue VERSION_DEFAULT #File.read(File.join(File.expand_path(File.dirname(File.dirname(File.dirname(__FILE__)))), 'VERSION')) rescue VERSION_DEFAULT
|
6
4
|
VERSION.instance_eval do
|
7
5
|
def components; VERSION.split('.'); end
|
8
6
|
def major; components[0]; end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ginjo-rfm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 1.4.
|
9
|
+
- 4
|
10
|
+
version: 1.4.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Geoff Coffey
|
@@ -19,7 +19,7 @@ autorequire:
|
|
19
19
|
bindir: bin
|
20
20
|
cert_chain: []
|
21
21
|
|
22
|
-
date: 2011-
|
22
|
+
date: 2011-12-06 00:00:00 Z
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
25
25
|
name: nokogiri
|
@@ -35,6 +35,78 @@ dependencies:
|
|
35
35
|
version: "0"
|
36
36
|
type: :runtime
|
37
37
|
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: jeweler
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 3
|
47
|
+
segments:
|
48
|
+
- 0
|
49
|
+
version: "0"
|
50
|
+
type: :development
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: rake
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
type: :development
|
65
|
+
version_requirements: *id003
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: rdoc
|
68
|
+
prerelease: false
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: yard
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
type: :development
|
93
|
+
version_requirements: *id005
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rspec
|
96
|
+
prerelease: false
|
97
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ~>
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
hash: 27
|
103
|
+
segments:
|
104
|
+
- 1
|
105
|
+
- 3
|
106
|
+
- 0
|
107
|
+
version: 1.3.0
|
108
|
+
type: :development
|
109
|
+
version_requirements: *id006
|
38
110
|
description: Rfm brings your FileMaker data to Ruby. Now your Ruby scripts and Rails applications can talk directly to your FileMaker server.
|
39
111
|
email: http://groups.google.com/group/rfmcommunity
|
40
112
|
executables: []
|
@@ -69,7 +141,7 @@ post_install_message:
|
|
69
141
|
rdoc_options:
|
70
142
|
- --line-numbers
|
71
143
|
- --main
|
72
|
-
- README.
|
144
|
+
- README.md
|
73
145
|
require_paths:
|
74
146
|
- lib
|
75
147
|
required_ruby_version: !ruby/object:Gem::Requirement
|