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