lib/rfm/layout.rb in ginjo-rfm-2.0.pre31 vs lib/rfm/layout.rb in ginjo-rfm-2.0.0
- old
+ new
@@ -117,13 +117,11 @@
# * +value_lists+ is a hash of arrays. The keys are value list names, and the values in the hash
# are arrays containing the actual value list items. +value_lists+ will include every value
# list that is attached to any field on the layout
class Layout
-
- include ComplexQuery
-
+
# Initialize a layout object. You never really need to do this. Instead, just do this:
#
# myServer = Rfm::Server.new(...)
# myDatabase = myServer["Customers"]
# myLayout = myDatabase["Details"]
@@ -134,11 +132,11 @@
# In case it isn't obvious, this is more easily expressed this way:
#
# myServer = Rfm::Server.new(...)
# myLayout = myServer["Customers"]["Details"]
def initialize(name, db_obj)
- raise Rfm::Error::RfmError.new(0, "New instance of Rfm::Layout has no name.") if name.to_s == ''
+ raise Rfm::Error::RfmError.new(0, "New instance of Rfm::Layout has no name. Attempted name '#{name}'.") if name.to_s == ''
@name = name.to_s
rfm_metaclass.instance_variable_set :@db, db_obj
@loaded = false
@field_controls = Rfm::CaseInsensitiveHash.new
@@ -154,10 +152,14 @@
alias_method :database, :db
# These methods are to be inclulded in Layout and SubLayout, so that
# they have their own descrete 'self' in the master class and the subclass.
+ # This means these methods will not get forwarded, and will talk to the correct
+ # variables & objects of the correct self.
+ # Do not get or set instance variables in Layout from other objects directly,
+ # always use getter & setter methods.
module LayoutModule
# Returns a ResultSet object containing _every record_ in the table associated with this layout.
def all(options = {})
get_records('-findall', {}, options)
@@ -173,19 +175,35 @@
# myLayout.find({"First Name" => "Bill"})
#
# Values in the hash work just like value in FileMaker's Find mode. You can use any special
# symbols (+==+, +...+, +>+, etc...).
#
- # If you pass anything other than a hash as the first parameter, it is converted to a string and
+ # Create a Filemaker 'omit' request by including an :omit key with a value of true.
+ #
+ # myLayout.find :field1 => 'val1', :field2 => 'val2', :omit => true
+ #
+ # Create multiple Filemaker find requests by passing an array of hashes to the #find method.
+ #
+ # myLayout.find [{:field1 => 'bill', :field2 => 'admin'}, {:field3 => 'inactive', :omit => true}, ...]
+ #
+ # If the value of a field in a find request is an array of strings, the string values will be logically OR'd in the query.
+ #
+ # myLayout.find :fieldOne => ['bill','mike','bob'], :fieldTwo =>'staff'
+ #
+ # If you pass anything other than a hash or an array as the first parameter, it is converted to a string and
# assumed to be FileMaker's internal id for a record (the recid).
- def find(hash_or_recid, options = {})
- if hash_or_recid.kind_of? Hash
- get_records('-find', hash_or_recid, options)
- else
- get_records('-find', {'-recid' => hash_or_recid.to_s}, options)
- end
+ #
+ # myLayout.find 54321
+ #
+ def find(find_criteria, options = {})
+ get_records(*Rfm::CompoundQuery.new(find_criteria, options))
end
+
+ # Access to raw -findquery command.
+ def query(query_hash, options = {})
+ get_records('-findquery', query_hash, options)
+ end
# Updates the contents of the record whose internal +recid+ is specified. Send in a hash of new
# data in the +values+ parameter. Returns a RecordSet containing the modified record. For example:
#
# recid = myLayout.find({"First Name" => "Bill"})[0].record_id
@@ -193,10 +211,11 @@
#
# The above code would find the first record with _Bill_ in the First Name field and change the
# first name to _Steve_.
def edit(recid, values, options = {})
get_records('-edit', {'-recid' => recid}.merge(values), options)
+ #get_records('-edit', {'-recid' => recid}.merge(expand_repeats(values)), options) # attempt to set repeating fields.
end
# Creates a new record in the table associated with this layout. Pass field data as a hash in the
# +values+ parameter. Returns the newly created record in a RecordSet. You can use the returned
# record to, ie, discover the values in auto-enter fields (like serial numbers).
@@ -223,19 +242,46 @@
def delete(recid, options = {})
get_records('-delete', {'-recid' => recid}, options)
return nil
end
+ # Retrieves metadata only, with an empty resultset.
+ def view(options = {})
+ get_records('-view', {}, options)
+ end
+
def get_records(action, extra_params = {}, options = {})
include_portals = options[:include_portals] ? options.delete(:include_portals) : nil
xml_response = db.server.connect(db.account_name, db.password, action, params.merge(extra_params), options).body
Rfm::Resultset.new(db.server, xml_response, self, include_portals)
end
def params
{"-db" => db.name, "-lay" => self.name}
end
+
+
+ # Intended to set each repeat individually but doesn't work with FM
+ def expand_repeats(hash)
+ hash.each do |key,val|
+ if val.kind_of? Array
+ val.each_with_index{|v, i| hash["#{key}(#{i+1})"] = v}
+ hash.delete(key)
+ end
+ end
+ hash
+ end
+
+ # Intended to brute-force repeat setting but doesn't work with FM
+ def join_repeats(hash)
+ hash.each do |key,val|
+ if val.kind_of? Array
+ hash[key] = val.join('\x1D')
+ end
+ end
+ hash
+ end
end # LayoutModule
include LayoutModule
@@ -256,16 +302,20 @@
def value_lists
load unless @loaded
@value_lists
end
+ def count(find_criteria, options={})
+ find(find_criteria, options.merge({:max_records => 0})).foundset_count
+ end
+
def total_count
- any.total_count
+ view.total_count
end
def portal_meta
- @portal_meta ||= any.portal_meta
+ @portal_meta ||= view.portal_meta
end
def portal_meta_no_load
@portal_meta
end
@@ -273,10 +323,10 @@
def portal_names
portal_meta.keys
end
def table
- @table ||= any.table
+ @table ||= view.table
end
def table_no_load
@table
end
\ No newline at end of file