Class: Rfm::Server
Overview
The Database object represents a single FileMaker Pro database. When you retrieve a Database object from a server, its account name and password are set to the account name and password you used when initializing the Server object. You can override this of course:
myDatabase = myServer["Customers"]
myDatabase.account_name = "foo"
myDatabase.password = "bar"
Accessing Layouts
All interaction with FileMaker happens through a Layout object. You can get a Layout object from the Database object like this:
myLayout = myDatabase["Details"]
This code gets the Layout object representing the layout called Details in the database.
Note: RFM does not talk to the server when you retrieve a Layout object in this way. Instead, it simply assumes you know what you’re talking about. If the layout you specify does not exist, you will get no error at this point. Instead, you’ll get an error when you use the Layout object methods to talk to FileMaker. This makes debugging a little less convenient, but it would introduce too much overhead to hit the server at this point.
The Database object has a layout
attribute that provides alternate access to Layout objects. It acts like a hash of Layout objects, one for each accessible layout in the database. So, for example, you can do this if you want to print out a list of all layouts:
myDatabase.layout.each {|layout|
puts layout.name
}
The Database::layout attribute is actually a LayoutFactory object, although it subclasses hash, so it should work in all the ways you expect. Note, though, that it is completely empty until the first time you attempt to access its elements. At that (lazy) point, it hits FileMaker, loads in the list of layouts, and constructs a Layout object for each one. In other words, it incurrs no overhead until you use it.
Accessing Scripts
If for some reason you need to enumerate the scripts in a database, you can do so:
myDatabase.script.each {|script|
puts script.name
}
The Database::script attribute is actually a ScriptFactory object, although it subclasses hash, so it should work in all the ways you expect. Note, though, that it is completely empty until the first time you attempt to access its elements. At that (lazy) point, it hits FileMaker, loads in the list of scripts, and constructs a Script object for each one. In other words, it incurrs no overhead until you use it.
Note: You don’t need a Script object to run a script (see the Layout object instead).
Attributes
In addition to the layout
attribute, Server has a few other useful attributes:
-
server is the Server object this database comes from
-
name is the name of this database
-
state is a hash of all server options used to initialize this server
Instance Attribute Summary collapse
-
#databases ⇒ Object
(also: #db)
readonly
, :host_name, :port, :scheme, :state.
Instance Method Summary collapse
-
#connect(account_name, password, action, args, options = {}) ⇒ Object
Performs a raw FileMaker action.
- #host_name ⇒ Object
-
#initialize(*args) ⇒ Server
constructor
To create a Server object, you typically need at least a host name:.
- #load_layout(layout) ⇒ Object
- #port ⇒ Object
-
#remove_namespace(xml) ⇒ Object
Removes namespace from fmpxmllayout, so xpath will work.
- #scheme ⇒ Object
- #select_grammar(post, options = {}) ⇒ Object
- #state(*args) ⇒ Object
Methods included from Config
#config, #config_clear, #get_config, #sanitize_config
Constructor Details
#initialize(*args) ⇒ Server
To create a Server object, you typically need at least a host name:
myServer = Rfm::Server.new({:host => 'my.host.com'})
Several other options are supported
-
host the hostname of the Web Publishing Engine (WPE) server (defaults to ‘localhost’)
-
port the port number the WPE is listening no (defaults to 80 unless ssl
true
which sets it to 443) -
account_name the default account name to log in to databases with (you can also supply a account name on a per-database basis if necessary)
-
password the default password to log in to databases with (you can also supplly a password on a per-databases basis if necessary)
-
log_actions when
true
, RFM logs all action URLs that are sent to FileMaker server to stderr (defaults tofalse
) -
log_responses when
true
, RFM logs all raw XML responses (including headers) from FileMaker to stderr (defaults tofalse
) -
warn_on_redirect normally, RFM prints a warning to stderr if the Web Publishing Engine redirects (this can usually be fixed by using a different host name, which speeds things up); if you *don’t* want this warning printed, set
warn_on_redirect
totrue
-
raise_on_401 although RFM raises error when FileMaker returns error responses, it typically ignores FileMaker’s 401 error (no records found) and returns an empty record set instead; if you prefer a raised error when a find produces no errors, set this option to
true
SSL Options (SSL AND CERTIFICATE VERIFICATION ARE ON BY DEFAULT)
-
ssl
false
if you want to turn SSL (HTTPS) off when connecting to connect to FileMaker (default istrue
)
If you are using SSL and want to verify the certificate, use the following options:
-
root_cert
true
is the default. If you do not want to verify your SSL session, set this tofalse
. You will want to turn this off if you are using a self signed certificate and do not have a certificate authority cert file. If you choose this option you will need to provide a cert root_cert_name and root_cert_path (if not in root directory). -
root_cert_name name of pem file for certificate verification (Root cert from certificate authority who issued certificate. If self signed certificate do not use this option!!). You can download the entire bundle of CA Root Certificates from curl.haxx.se/ca/cacert.pem. Place the pem file in config directory.
-
root_cert_path path to cert file. (defaults to ‘/’ if no path given)
Configuration Examples
Example to turn off SSL:
myServer = Rfm::Server.new({
:host => 'localhost',
:account_name => 'sample',
:password => '12345',
:ssl => false
})
Example using SSL without root_cert:
myServer = Rfm::Server.new({
:host => 'localhost',
:account_name => 'sample',
:password => '12345',
:root_cert => false
})
Example using SSL with root_cert at file root:
myServer = Rfm::Server.new({
:host => 'localhost',
:account_name => 'sample',
:password => '12345',
:root_cert_name => 'example.pem'
})
Example using SSL with root_cert specifying root_cert_path:
myServer = Rfm::Server.new({
:host => 'localhost',
:account_name => 'sample',
:password => '12345',
:root_cert_name => 'example.pem'
:root_cert_path => '/usr/cert_file/'
})
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/rfm/server.rb', line 198 def initialize(*args) config :parent => 'Rfm::Config' = get_config(*args) config sanitize_config(, {}, true) config(:host => ([:strings].delete_at(0) || [:host]) ) raise Rfm::Error::RfmError.new(0, "New instance of Rfm::Server has no host name. Attempted name '#{config[:host]}'.") if config[:host].to_s == '' @defaults = { :host => 'localhost', :port => 80, :ssl => true, :root_cert => true, :root_cert_name => '', :root_cert_path => '/', :account_name => '', :password => '', :log_actions => false, :log_responses => false, :log_parser => false, :warn_on_redirect => true, :raise_on_401 => false, :timeout => 60, :ignore_bad_data => false, :grammar => 'fmresultset' } #.merge(options) @databases = Rfm::Factory::DbFactory.new(self) end |
Instance Attribute Details
#databases ⇒ Object (readonly) Also known as: db
, :host_name, :port, :scheme, :state
244 245 246 |
# File 'lib/rfm/server.rb', line 244 def databases @databases end |
Instance Method Details
#connect(account_name, password, action, args, options = {}) ⇒ Object
Performs a raw FileMaker action. You will generally not call this method directly, but it is exposed in case you need to do something “under the hood.”
The action
parameter is any valid FileMaker web url action. For example, -find
, -finadny
etc.
The args
parameter is a hash of arguments to be included in the action url. It will be serialized and url-encoded appropriately.
The options
parameter is a hash of RFM-specific options, which correspond to the more esoteric FileMaker URL parameters. They are exposed separately because they can also be passed into various methods on the Layout object, which is a much more typical way of sending an action to FileMaker.
This method returns the Net::HTTP response object representing the response from FileMaker.
For example, if you wanted to send a raw command to FileMaker to find the first 20 people in the “Customers” database whose first name is “Bill” you might do this:
response = myServer.connect(
'-find',
{
"-db" => "Customers",
"-lay" => "Details",
"First Name" => "Bill"
},
{ :max_records => 20 }
)
283 284 285 286 287 288 |
# File 'lib/rfm/server.rb', line 283 def connect(account_name, password, action, args, = {}) grammar_option = .delete(:grammar) post = args.merge(()).merge({action => ''}) grammar = select_grammar(post, :grammar=>grammar_option) http_fetch(host_name, port, "/fmi/xml/#{grammar}.xml", account_name, password, post) end |
#host_name ⇒ Object
252 |
# File 'lib/rfm/server.rb', line 252 def host_name; state[:host]; end |
#load_layout(layout) ⇒ Object
290 291 292 293 294 |
# File 'lib/rfm/server.rb', line 290 def load_layout(layout) post = {'-db' => layout.db.name, '-lay' => layout.name, '-view' => ''} resp = http_fetch(host_name, port, "/fmi/xml/FMPXMLLAYOUT.xml", layout.db.account_name, layout.db.password, post) #remove_namespace(resp.body) end |
#port ⇒ Object
254 |
# File 'lib/rfm/server.rb', line 254 def port; state[:ssl] && state[:port].nil? ? 443 : state[:port]; end |
#remove_namespace(xml) ⇒ Object
Removes namespace from fmpxmllayout, so xpath will work
306 307 308 |
# File 'lib/rfm/server.rb', line 306 def remove_namespace(xml) xml.gsub(/xmlns=\"[^\"]*\"/, '') end |
#scheme ⇒ Object
253 |
# File 'lib/rfm/server.rb', line 253 def scheme; state[:ssl] ? "https" : "http"; end |
#select_grammar(post, options = {}) ⇒ Object
296 297 298 299 300 301 302 303 |
# File 'lib/rfm/server.rb', line 296 def select_grammar(post, ={}) grammar = state()[:grammar] || 'fmresultset' if grammar.to_s.downcase == 'auto' post.keys.find(){|k| %w(-find -findall -dbnames -layoutnames -scriptnames).include? k.to_s} ? "FMPXMLRESULT" : "fmresultset" else grammar end end |
#state(*args) ⇒ Object
248 249 250 |
# File 'lib/rfm/server.rb', line 248 def state(*args) @defaults.merge(get_config(*args)) end |