ginjo-rfm 1.4.4 → 2.0.pre31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +107 -0
 - data/README.md +378 -133
 - data/lib/rfm.rb +51 -19
 - data/lib/rfm/VERSION +1 -1
 - data/lib/rfm/base.rb +416 -0
 - data/lib/rfm/database.rb +14 -9
 - data/lib/rfm/layout.rb +148 -96
 - data/lib/rfm/metadata/field.rb +5 -5
 - data/lib/rfm/metadata/field_control.rb +52 -51
 - data/lib/rfm/metadata/script.rb +7 -5
 - data/lib/rfm/record.rb +71 -56
 - data/lib/rfm/resultset.rb +45 -26
 - data/lib/rfm/server.rb +21 -17
 - data/lib/rfm/utilities/complex_query.rb +64 -0
 - data/lib/rfm/utilities/config.rb +115 -0
 - data/lib/rfm/utilities/core_ext.rb +90 -0
 - data/lib/rfm/utilities/factory.rb +100 -17
 - data/lib/rfm/utilities/xml_parser.rb +94 -0
 - data/lib/rfm/version.rb +1 -1
 - data/lib/rfm/xml_mini/hpricot.rb +133 -0
 - metadata +87 -30
 
| 
         @@ -0,0 +1,115 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Rfm
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            	# Top level config hash accepts any defined config parameters,
         
     | 
| 
      
 4 
     | 
    
         
            +
            	# or group-name keys pointing to config subsets.
         
     | 
| 
      
 5 
     | 
    
         
            +
            	# The subsets can be any grouping of defined config parameters, as a hash.
         
     | 
| 
      
 6 
     | 
    
         
            +
            	# See CONFIG_KEYS for defined config parameters.
         
     | 
| 
      
 7 
     | 
    
         
            +
            	#
         
     | 
| 
      
 8 
     | 
    
         
            +
            	# All filters are honored, unless filters are included in calls to get_config,
         
     | 
| 
      
 9 
     | 
    
         
            +
            	# in which case only the immediately specified filters will be used.
         
     | 
| 
      
 10 
     | 
    
         
            +
            	#
         
     | 
| 
      
 11 
     | 
    
         
            +
            	# Do not put a :use=>:group filter in a subset (maybe future feature?).
         
     | 
| 
      
 12 
     | 
    
         
            +
            	# Do not put a :use=>:group filter in the top-level global parameters.
         
     | 
| 
      
 13 
     | 
    
         
            +
            	# Do not put subsets in non-top-level configs. (maybe future feature?)
         
     | 
| 
      
 14 
     | 
    
         
            +
            	#
         
     | 
| 
      
 15 
     | 
    
         
            +
              module Config
         
     | 
| 
      
 16 
     | 
    
         
            +
              	CONFIG_KEYS = %w(parser host port account_name password database layout ssl root_cert root_cert_name root_cert_path warn_on_redirect raise_on_401 timeout log_actions log_responses log_parser use parent)
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                extend self
         
     | 
| 
      
 19 
     | 
    
         
            +
                @config = {}
         
     | 
| 
      
 20 
     | 
    
         
            +
            	  	  
         
     | 
| 
      
 21 
     | 
    
         
            +
            	  # Set @config with args & options hash.
         
     | 
| 
      
 22 
     | 
    
         
            +
            	  # Args should be symbols representing configuration groups,
         
     | 
| 
      
 23 
     | 
    
         
            +
            	  # with optional config hash as last arg, to be merged on top.
         
     | 
| 
      
 24 
     | 
    
         
            +
            	  # Returns @config.
         
     | 
| 
      
 25 
     | 
    
         
            +
            	  #
         
     | 
| 
      
 26 
     | 
    
         
            +
            	  # == Sets @config with :use => :group1, :layout => 'my_layout'
         
     | 
| 
      
 27 
     | 
    
         
            +
            	  #    config :group1, :layout => 'my_layout
         
     | 
| 
      
 28 
     | 
    
         
            +
            	  #
         
     | 
| 
      
 29 
     | 
    
         
            +
            	  # Factory.server, Factory.database, Factory.layout, and Base.config can take
         
     | 
| 
      
 30 
     | 
    
         
            +
            	  # a string as the first argument, refering to the relevent server/database/layout name.
         
     | 
| 
      
 31 
     | 
    
         
            +
            	  #
         
     | 
| 
      
 32 
     | 
    
         
            +
            	  # == Pass a string as the first argument, to be used in the immediate context
         
     | 
| 
      
 33 
     | 
    
         
            +
            	  #    config 'my_layout'                     # in the model, to set model configuration
         
     | 
| 
      
 34 
     | 
    
         
            +
            	  #    Factory.layout 'my_layout', :my_group  # to get a layout from settings in :my_group
         
     | 
| 
      
 35 
     | 
    
         
            +
            	  #
         
     | 
| 
      
 36 
     | 
    
         
            +
            	  def config(*args, &block)
         
     | 
| 
      
 37 
     | 
    
         
            +
            	  	opt = args.rfm_extract_options!
         
     | 
| 
      
 38 
     | 
    
         
            +
            	  	@config ||= {}
         
     | 
| 
      
 39 
     | 
    
         
            +
            			config_write(opt, args, &block)
         
     | 
| 
      
 40 
     | 
    
         
            +
            			@config
         
     | 
| 
      
 41 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 42 
     | 
    
         
            +
            	  
         
     | 
| 
      
 43 
     | 
    
         
            +
            	  # Sets @config just as above config method, but clears @config first.
         
     | 
| 
      
 44 
     | 
    
         
            +
            	  def config_clear(*args)
         
     | 
| 
      
 45 
     | 
    
         
            +
            	  	opt = args.rfm_extract_options!
         
     | 
| 
      
 46 
     | 
    
         
            +
            	  	@config = {}
         
     | 
| 
      
 47 
     | 
    
         
            +
            			config_write(opt, args)
         
     | 
| 
      
 48 
     | 
    
         
            +
            			@config
         
     | 
| 
      
 49 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 50 
     | 
    
         
            +
            	  
         
     | 
| 
      
 51 
     | 
    
         
            +
            	  # Reads compiled config, including filters and ad-hoc configuration params passed in.
         
     | 
| 
      
 52 
     | 
    
         
            +
            	  # If first n parameters are strings, they will be appended to config[:strings].
         
     | 
| 
      
 53 
     | 
    
         
            +
            	  # If next n parameters are symbols, they will be used to filter the result. These
         
     | 
| 
      
 54 
     | 
    
         
            +
            	  # filters will override all stored config[:use] settings.
         
     | 
| 
      
 55 
     | 
    
         
            +
            	  # The final optional hash should be ad-hoc config settings.
         
     | 
| 
      
 56 
     | 
    
         
            +
            	  #
         
     | 
| 
      
 57 
     | 
    
         
            +
            	  # == Gets top level settings, merged with group settings, merged with local and ad-hoc settings.
         
     | 
| 
      
 58 
     | 
    
         
            +
            	  #    get_config :my_server_group, :layout => 'my_layout'  # This gets top level settings,
         
     | 
| 
      
 59 
     | 
    
         
            +
            		#
         
     | 
| 
      
 60 
     | 
    
         
            +
            		# == Gets top level settings, merged with local and ad-hoc settings.
         
     | 
| 
      
 61 
     | 
    
         
            +
            		#    get_config :layout => 'my_layout
         
     | 
| 
      
 62 
     | 
    
         
            +
            		#
         
     | 
| 
      
 63 
     | 
    
         
            +
              	def get_config(*args)
         
     | 
| 
      
 64 
     | 
    
         
            +
              		@config ||= {}
         
     | 
| 
      
 65 
     | 
    
         
            +
              		opt = args.rfm_extract_options!
         
     | 
| 
      
 66 
     | 
    
         
            +
              		strings = []
         
     | 
| 
      
 67 
     | 
    
         
            +
              		while args[0].is_a?(String) do; strings << args.shift; end
         
     | 
| 
      
 68 
     | 
    
         
            +
            	    if args.size == 0
         
     | 
| 
      
 69 
     | 
    
         
            +
            	    	config_filter(config_merge_with_parent)
         
     | 
| 
      
 70 
     | 
    
         
            +
            	    else
         
     | 
| 
      
 71 
     | 
    
         
            +
            	    	config_filter(config_merge_with_parent, args)
         
     | 
| 
      
 72 
     | 
    
         
            +
            	    end.merge(opt).merge(:strings=>strings)
         
     | 
| 
      
 73 
     | 
    
         
            +
              	end
         
     | 
| 
      
 74 
     | 
    
         
            +
              		  
         
     | 
| 
      
 75 
     | 
    
         
            +
            	protected
         
     | 
| 
      
 76 
     | 
    
         
            +
            	  
         
     | 
| 
      
 77 
     | 
    
         
            +
            	  
         
     | 
| 
      
 78 
     | 
    
         
            +
            		# Merge args into @config, as :use=>[arg1, arg2, ...]
         
     | 
| 
      
 79 
     | 
    
         
            +
            		# Then merge optional config hash into @config.
         
     | 
| 
      
 80 
     | 
    
         
            +
            		# Pass in a block to use with strings in args. See base.rb.
         
     | 
| 
      
 81 
     | 
    
         
            +
            	  def config_write(opt, args)
         
     | 
| 
      
 82 
     | 
    
         
            +
            	  	strings = []; while args[0].is_a?(String) do; strings << args.shift; end
         
     | 
| 
      
 83 
     | 
    
         
            +
            	  	args.each{|a| @config.merge!(:use=>a.to_sym)}
         
     | 
| 
      
 84 
     | 
    
         
            +
            	  	@config.merge!(opt)
         
     | 
| 
      
 85 
     | 
    
         
            +
            	  	yield(strings) if block_given?
         
     | 
| 
      
 86 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 87 
     | 
    
         
            +
            	  	
         
     | 
| 
      
 88 
     | 
    
         
            +
            	  # Get composite config from all levels, adding :use parameters to a
         
     | 
| 
      
 89 
     | 
    
         
            +
            	  # temporary top-level value.
         
     | 
| 
      
 90 
     | 
    
         
            +
            	  def config_merge_with_parent
         
     | 
| 
      
 91 
     | 
    
         
            +
                  remote = if (self != Rfm::Config) 
         
     | 
| 
      
 92 
     | 
    
         
            +
                  	eval(@config[:parent] || 'Rfm::Config').config_merge_with_parent rescue {}
         
     | 
| 
      
 93 
     | 
    
         
            +
                  else
         
     | 
| 
      
 94 
     | 
    
         
            +
                  	(defined?(RFM_CONFIG) and RFM_CONFIG.is_a?(Hash)) ? RFM_CONFIG : {}
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  
         
     | 
| 
      
 97 
     | 
    
         
            +
                  use = (remote[:use].rfm_force_array | @config[:use].rfm_force_array).compact
         
     | 
| 
      
 98 
     | 
    
         
            +
            			remote.merge(@config).merge(:use=>use)
         
     | 
| 
      
 99 
     | 
    
         
            +
                end	  
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            		# Given config hash, return filtered. Filters should be symbols.
         
     | 
| 
      
 102 
     | 
    
         
            +
            		def config_filter(conf, filters=nil)
         
     | 
| 
      
 103 
     | 
    
         
            +
            			filters ||= conf[:use].rfm_force_array if !conf[:use].blank?
         
     | 
| 
      
 104 
     | 
    
         
            +
            			filters.each{|f| next unless conf[f]; conf.merge!(conf[f] || {})} if !filters.blank?
         
     | 
| 
      
 105 
     | 
    
         
            +
            			conf.reject!{|k,v| !CONFIG_KEYS.include?(k.to_s) or v.to_s == '' }
         
     | 
| 
      
 106 
     | 
    
         
            +
            			conf
         
     | 
| 
      
 107 
     | 
    
         
            +
            		end
         
     | 
| 
      
 108 
     | 
    
         
            +
                
         
     | 
| 
      
 109 
     | 
    
         
            +
                # This loads RFM_CONFIG into @config. It is not necessary,
         
     | 
| 
      
 110 
     | 
    
         
            +
                # as get_config will merge all configuration into RFM_CONFIG at runtime.
         
     | 
| 
      
 111 
     | 
    
         
            +
                #config RFM_CONFIG if defined? RFM_CONFIG
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            	end # module Config
         
     | 
| 
      
 114 
     | 
    
         
            +
            	
         
     | 
| 
      
 115 
     | 
    
         
            +
            end # module Rfm
         
     | 
| 
         @@ -0,0 +1,90 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'forwardable'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Module.module_eval do
         
     | 
| 
      
 4 
     | 
    
         
            +
            	# Adds ability to forward methods to other objects using 'def_delegator'
         
     | 
| 
      
 5 
     | 
    
         
            +
            	include Forwardable
         
     | 
| 
      
 6 
     | 
    
         
            +
            end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            class Object # @private :nodoc: all
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            	#extend Forwardable
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            	# Adds methods to put instance variables in rfm_metaclass, plus getter/setters
         
     | 
| 
      
 13 
     | 
    
         
            +
            	# This is useful to hide instance variables in objects that would otherwise show "too much" information.
         
     | 
| 
      
 14 
     | 
    
         
            +
              def self.meta_attr_accessor(*names)
         
     | 
| 
      
 15 
     | 
    
         
            +
            		meta_attr_reader(*names)
         
     | 
| 
      
 16 
     | 
    
         
            +
            		meta_attr_writer(*names)
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              
         
     | 
| 
      
 19 
     | 
    
         
            +
              def self.meta_attr_reader(*names)
         
     | 
| 
      
 20 
     | 
    
         
            +
                names.each do |n|
         
     | 
| 
      
 21 
     | 
    
         
            +
                  define_method(n.to_s) {rfm_metaclass.instance_variable_get("@#{n}")}
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
              
         
     | 
| 
      
 25 
     | 
    
         
            +
              def self.meta_attr_writer(*names)
         
     | 
| 
      
 26 
     | 
    
         
            +
                names.each do |n|
         
     | 
| 
      
 27 
     | 
    
         
            +
                  define_method(n.to_s + "=") {|val| rfm_metaclass.instance_variable_set("@#{n}", val)}
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              
         
     | 
| 
      
 31 
     | 
    
         
            +
              # Wrap an object in Array, if not already an Array,
         
     | 
| 
      
 32 
     | 
    
         
            +
            	# since XmlMini doesn't know which will be returnd for any particular element.
         
     | 
| 
      
 33 
     | 
    
         
            +
            	# See Rfm Layout & Record where this is used.
         
     | 
| 
      
 34 
     | 
    
         
            +
            	def rfm_force_array
         
     | 
| 
      
 35 
     | 
    
         
            +
            		self.is_a?(Array) ? self : [self]
         
     | 
| 
      
 36 
     | 
    
         
            +
            	end
         
     | 
| 
      
 37 
     | 
    
         
            +
            	
         
     | 
| 
      
 38 
     | 
    
         
            +
            	# Just testing this functionality
         
     | 
| 
      
 39 
     | 
    
         
            +
            	def local_methods
         
     | 
| 
      
 40 
     | 
    
         
            +
            		self.methods - self.class.superclass.methods
         
     | 
| 
      
 41 
     | 
    
         
            +
            	end
         
     | 
| 
      
 42 
     | 
    
         
            +
              
         
     | 
| 
      
 43 
     | 
    
         
            +
            private
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            	# Like singleton_method or 'metaclass' from ActiveSupport.
         
     | 
| 
      
 46 
     | 
    
         
            +
            	def rfm_metaclass
         
     | 
| 
      
 47 
     | 
    
         
            +
            		class << self
         
     | 
| 
      
 48 
     | 
    
         
            +
            			self
         
     | 
| 
      
 49 
     | 
    
         
            +
            		end
         
     | 
| 
      
 50 
     | 
    
         
            +
            	end
         
     | 
| 
      
 51 
     | 
    
         
            +
              
         
     | 
| 
      
 52 
     | 
    
         
            +
              # Get the superclass object of self.
         
     | 
| 
      
 53 
     | 
    
         
            +
              def rfm_super
         
     | 
| 
      
 54 
     | 
    
         
            +
                SuperProxy.new(self)
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
              
         
     | 
| 
      
 57 
     | 
    
         
            +
            end # Object
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            class Array
         
     | 
| 
      
 61 
     | 
    
         
            +
            	# Taken from ActiveSupport extract_options!.
         
     | 
| 
      
 62 
     | 
    
         
            +
            	def rfm_extract_options!
         
     | 
| 
      
 63 
     | 
    
         
            +
            	  last.is_a?(::Hash) ? pop : {}
         
     | 
| 
      
 64 
     | 
    
         
            +
            	end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end # Array
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            # Allows access to superclass object
         
     | 
| 
      
 68 
     | 
    
         
            +
            class SuperProxy
         
     | 
| 
      
 69 
     | 
    
         
            +
              def initialize(obj)
         
     | 
| 
      
 70 
     | 
    
         
            +
                @obj = obj
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              def method_missing(meth, *args, &blk)
         
     | 
| 
      
 74 
     | 
    
         
            +
                @obj.class.superclass.instance_method(meth).bind(@obj).call(*args, &blk)
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
            end # SuperProxy
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            class Time
         
     | 
| 
      
 80 
     | 
    
         
            +
            	# Returns array of [date,time] in format suitable for FMP.
         
     | 
| 
      
 81 
     | 
    
         
            +
            	def to_fm_components(reset_time_if_before_today=false)
         
     | 
| 
      
 82 
     | 
    
         
            +
            		d = self.strftime('%m/%d/%Y')
         
     | 
| 
      
 83 
     | 
    
         
            +
            		t = if (Date.parse(self.to_s) < Date.today) and reset_time_if_before_today==true
         
     | 
| 
      
 84 
     | 
    
         
            +
            			"00:00:00"
         
     | 
| 
      
 85 
     | 
    
         
            +
            		else
         
     | 
| 
      
 86 
     | 
    
         
            +
            			self.strftime('%T')
         
     | 
| 
      
 87 
     | 
    
         
            +
            		end
         
     | 
| 
      
 88 
     | 
    
         
            +
            		[d,t]
         
     | 
| 
      
 89 
     | 
    
         
            +
            	end
         
     | 
| 
      
 90 
     | 
    
         
            +
            end # Time
         
     | 
| 
         @@ -7,32 +7,64 @@ 
     | 
|
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            module Rfm
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              module Factory 
         
     | 
| 
      
 12 
     | 
    
         
            +
              	extend Config
         
     | 
| 
      
 13 
     | 
    
         
            +
              	config :parent=>'Rfm::Config'
         
     | 
| 
      
 14 
     | 
    
         
            +
              
         
     | 
| 
      
 15 
     | 
    
         
            +
              	class ServerFactory < Rfm::CaseInsensitiveHash # @private :nodoc: all
         
     | 
| 
      
 16 
     | 
    
         
            +
                  
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def [](host, conf = Factory.get_config) #(Factory.instance_variable_get(:@config) || {}))
         
     | 
| 
      
 18 
     | 
    
         
            +
                  	conf[:host] = host
         
     | 
| 
      
 19 
     | 
    
         
            +
                    super(host) or (self[host] = Rfm::Server.new(conf.reject{|k,v| [:account_name, :password].include? k}))
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
            			
         
     | 
| 
      
 22 
     | 
    
         
            +
            			# Potential refactor
         
     | 
| 
      
 23 
     | 
    
         
            +
            			# 		def [](*conf)
         
     | 
| 
      
 24 
     | 
    
         
            +
            			# 			options = Factory.get_config(*conf)
         
     | 
| 
      
 25 
     | 
    
         
            +
            			#   		server_name = options[:strings][0] || options[:host]
         
     | 
| 
      
 26 
     | 
    
         
            +
            			#   		options[:host] = server_name
         
     | 
| 
      
 27 
     | 
    
         
            +
            			# 			#server = servers[server_name, options]
         
     | 
| 
      
 28 
     | 
    
         
            +
            			# 			super(server_name) or (self[server_name] = Rfm::Server.new(options.reject{|k,v| [:account_name, :password].include? k}))
         
     | 
| 
      
 29 
     | 
    
         
            +
            			# 		end
         
     | 
| 
      
 30 
     | 
    
         
            +
                
         
     | 
| 
      
 31 
     | 
    
         
            +
                end # ServerFactory
         
     | 
| 
      
 32 
     | 
    
         
            +
                
         
     | 
| 
      
 33 
     | 
    
         
            +
                
         
     | 
| 
      
 34 
     | 
    
         
            +
                class DbFactory < Rfm::CaseInsensitiveHash # :nodoc: all
         
     | 
| 
       12 
35 
     | 
    
         | 
| 
       13 
36 
     | 
    
         
             
                  def initialize(server)
         
     | 
| 
       14 
37 
     | 
    
         
             
                    @server = server
         
     | 
| 
       15 
38 
     | 
    
         
             
                    @loaded = false
         
     | 
| 
       16 
39 
     | 
    
         
             
                  end
         
     | 
| 
       17 
40 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
                  def [](dbname)
         
     | 
| 
       19 
     | 
    
         
            -
                    super or (self[dbname] = Rfm::Database.new(dbname, @server))
         
     | 
| 
      
 41 
     | 
    
         
            +
                  def [](dbname, acnt=nil, pass=nil) #
         
     | 
| 
      
 42 
     | 
    
         
            +
                    db = (super(dbname) or (self[dbname] = Rfm::Database.new(dbname, @server)))
         
     | 
| 
      
 43 
     | 
    
         
            +
                    account_name = acnt || db.account_name || @server.state[:account_name]
         
     | 
| 
      
 44 
     | 
    
         
            +
                    password = pass || db.password || @server.state[:password]
         
     | 
| 
      
 45 
     | 
    
         
            +
                    db.account_name = account_name if account_name
         
     | 
| 
      
 46 
     | 
    
         
            +
                    db.password = password if password
         
     | 
| 
      
 47 
     | 
    
         
            +
                    db
         
     | 
| 
       20 
48 
     | 
    
         
             
                  end
         
     | 
| 
       21 
49 
     | 
    
         | 
| 
       22 
50 
     | 
    
         
             
                  def all
         
     | 
| 
       23 
51 
     | 
    
         
             
                    if !@loaded
         
     | 
| 
       24 
52 
     | 
    
         
             
                      Rfm::Resultset.new(@server, @server.connect(@server.state[:account_name], @server.state[:password], '-dbnames', {}).body, nil).each {|record|
         
     | 
| 
       25 
53 
     | 
    
         
             
                        name = record['DATABASE_NAME']
         
     | 
| 
       26 
     | 
    
         
            -
                        self[name] = Rfm::Database.new(name, @server) if self 
     | 
| 
      
 54 
     | 
    
         
            +
                        self[name] = Rfm::Database.new(name, @server) if self.keys.find{|k| k.to_s.downcase == name.to_s.downcase} == nil
         
     | 
| 
       27 
55 
     | 
    
         
             
                      }
         
     | 
| 
       28 
56 
     | 
    
         
             
                      @loaded = true
         
     | 
| 
       29 
57 
     | 
    
         
             
                    end
         
     | 
| 
       30 
     | 
    
         
            -
                    self 
     | 
| 
      
 58 
     | 
    
         
            +
                    self
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
                  
         
     | 
| 
      
 61 
     | 
    
         
            +
                  def names
         
     | 
| 
      
 62 
     | 
    
         
            +
                  	keys
         
     | 
| 
       31 
63 
     | 
    
         
             
                  end
         
     | 
| 
       32 
64 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end # DbFactory
         
     | 
| 
       34 
66 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                class LayoutFactory < Rfm::CaseInsensitiveHash
         
     | 
| 
      
 67 
     | 
    
         
            +
                class LayoutFactory < Rfm::CaseInsensitiveHash # :nodoc: all
         
     | 
| 
       36 
68 
     | 
    
         | 
| 
       37 
69 
     | 
    
         
             
                  def initialize(server, database)
         
     | 
| 
       38 
70 
     | 
    
         
             
                    @server = server
         
     | 
| 
         @@ -46,18 +78,24 @@ module Rfm 
     | 
|
| 
       46 
78 
     | 
    
         | 
| 
       47 
79 
     | 
    
         
             
                  def all
         
     | 
| 
       48 
80 
     | 
    
         
             
                    if !@loaded
         
     | 
| 
       49 
     | 
    
         
            -
            	        Rfm::Resultset.new(@server, @server.connect(@ 
     | 
| 
      
 81 
     | 
    
         
            +
            	        Rfm::Resultset.new(@server, @server.connect(@database.account_name, @database.password, '-layoutnames', {"-db" => @database.name}).body, nil).each {|record|
         
     | 
| 
       50 
82 
     | 
    
         
             
            	          name = record['LAYOUT_NAME']
         
     | 
| 
       51 
83 
     | 
    
         
             
            	          self[name] = Rfm::Layout.new(name, @database) if self[name] == nil
         
     | 
| 
       52 
84 
     | 
    
         
             
            	        }
         
     | 
| 
       53 
85 
     | 
    
         
             
                      @loaded = true
         
     | 
| 
       54 
86 
     | 
    
         
             
                    end
         
     | 
| 
       55 
     | 
    
         
            -
                    self 
     | 
| 
      
 87 
     | 
    
         
            +
                    self
         
     | 
| 
       56 
88 
     | 
    
         
             
                  end
         
     | 
| 
       57 
89 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
      
 90 
     | 
    
         
            +
                	def names
         
     | 
| 
      
 91 
     | 
    
         
            +
                		keys
         
     | 
| 
      
 92 
     | 
    
         
            +
                	end
         
     | 
| 
      
 93 
     | 
    
         
            +
                	
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                
         
     | 
| 
      
 96 
     | 
    
         
            +
                end # LayoutFactory
         
     | 
| 
       59 
97 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                class ScriptFactory < Rfm::CaseInsensitiveHash
         
     | 
| 
      
 98 
     | 
    
         
            +
                class ScriptFactory < Rfm::CaseInsensitiveHash # :nodoc: all
         
     | 
| 
       61 
99 
     | 
    
         | 
| 
       62 
100 
     | 
    
         
             
                  def initialize(server, database)
         
     | 
| 
       63 
101 
     | 
    
         
             
                    @server = server
         
     | 
| 
         @@ -71,15 +109,60 @@ module Rfm 
     | 
|
| 
       71 
109 
     | 
    
         | 
| 
       72 
110 
     | 
    
         
             
                  def all
         
     | 
| 
       73 
111 
     | 
    
         
             
                    if !@loaded
         
     | 
| 
       74 
     | 
    
         
            -
                      Rfm::Resultset.new(@server, @server.connect(@ 
     | 
| 
      
 112 
     | 
    
         
            +
                      Rfm::Resultset.new(@server, @server.connect(@database.account_name, @database.password, '-scriptnames', {"-db" => @database.name}).body, nil).each {|record|
         
     | 
| 
       75 
113 
     | 
    
         
             
                        name = record['SCRIPT_NAME']
         
     | 
| 
       76 
114 
     | 
    
         
             
                        self[name] = Rfm::Metadata::Script.new(name, @database) if self[name] == nil
         
     | 
| 
       77 
115 
     | 
    
         
             
                      }
         
     | 
| 
       78 
116 
     | 
    
         
             
                      @loaded = true
         
     | 
| 
       79 
117 
     | 
    
         
             
                    end
         
     | 
| 
       80 
     | 
    
         
            -
                    self 
     | 
| 
      
 118 
     | 
    
         
            +
                    self
         
     | 
| 
       81 
119 
     | 
    
         
             
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
         
     | 
| 
      
 121 
     | 
    
         
            +
             			def names
         
     | 
| 
      
 122 
     | 
    
         
            +
             				keys
         
     | 
| 
      
 123 
     | 
    
         
            +
             			end
         
     | 
| 
      
 124 
     | 
    
         
            +
                
         
     | 
| 
      
 125 
     | 
    
         
            +
                end # ScriptFactory
         
     | 
| 
      
 126 
     | 
    
         
            +
                
         
     | 
| 
      
 127 
     | 
    
         
            +
                
         
     | 
| 
      
 128 
     | 
    
         
            +
                
         
     | 
| 
      
 129 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 130 
     | 
    
         
            +
                	
         
     | 
| 
      
 131 
     | 
    
         
            +
            			def servers
         
     | 
| 
      
 132 
     | 
    
         
            +
            				@servers ||= ServerFactory.new
         
     | 
| 
      
 133 
     | 
    
         
            +
            			end    
         
     | 
| 
      
 134 
     | 
    
         
            +
                
         
     | 
| 
      
 135 
     | 
    
         
            +
            	  	# Returns Rfm::Server instance, given config hash or array
         
     | 
| 
      
 136 
     | 
    
         
            +
            	  	def server(*conf)
         
     | 
| 
      
 137 
     | 
    
         
            +
            	  		options = get_config(*conf)
         
     | 
| 
      
 138 
     | 
    
         
            +
            	  		server_name = options[:strings][0] || options[:host]
         
     | 
| 
      
 139 
     | 
    
         
            +
            	  		raise Rfm::Error::RfmError.new(0, 'A host name is needed to create a server object.') if server_name.blank?
         
     | 
| 
      
 140 
     | 
    
         
            +
            				server = servers[server_name, options]
         
     | 
| 
      
 141 
     | 
    
         
            +
            		  end
         
     | 
| 
      
 142 
     | 
    
         
            +
            			# Potential refactor
         
     | 
| 
      
 143 
     | 
    
         
            +
            			#def_delegator 'Rfm::Factory::ServerFactory', :[], :server  #, :[]
         
     | 
| 
      
 144 
     | 
    
         
            +
            	  
         
     | 
| 
      
 145 
     | 
    
         
            +
            		  # Returns Rfm::Db instance, given config hash or array
         
     | 
| 
      
 146 
     | 
    
         
            +
            		  def db(*conf)
         
     | 
| 
      
 147 
     | 
    
         
            +
            	  		options = get_config(*conf)
         
     | 
| 
      
 148 
     | 
    
         
            +
            	  		db_name = options[:strings][0] || options[:database]
         
     | 
| 
      
 149 
     | 
    
         
            +
            	  		raise Rfm::Error::RfmError.new(0, 'A database name is needed to create a database object.') if db_name.blank?
         
     | 
| 
      
 150 
     | 
    
         
            +
            	  		account_name = options[:strings][1] || options[:account_name]
         
     | 
| 
      
 151 
     | 
    
         
            +
            	  		password = options[:strings][2] || options[:password]
         
     | 
| 
      
 152 
     | 
    
         
            +
            				db = server(options)[db_name, account_name, password]
         
     | 
| 
      
 153 
     | 
    
         
            +
            		  end
         
     | 
| 
      
 154 
     | 
    
         
            +
            		  
         
     | 
| 
      
 155 
     | 
    
         
            +
            		  alias_method :database, :db
         
     | 
| 
      
 156 
     | 
    
         
            +
            		  
         
     | 
| 
      
 157 
     | 
    
         
            +
            		  # Returns Rfm::Layout instance, given config hash or array
         
     | 
| 
      
 158 
     | 
    
         
            +
            	  	def layout(*conf)
         
     | 
| 
      
 159 
     | 
    
         
            +
            	  		options = get_config(*conf)
         
     | 
| 
      
 160 
     | 
    
         
            +
            	  		layout_name = options[:strings][0] || options[:layout]
         
     | 
| 
      
 161 
     | 
    
         
            +
            	  		raise Rfm::Error::RfmError.new(0, 'A layout name is needed to create a layout object.') if layout_name.blank?
         
     | 
| 
      
 162 
     | 
    
         
            +
            				layout = db(options)[layout_name]
         
     | 
| 
      
 163 
     | 
    
         
            +
            	  	end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                end # class << self
         
     | 
| 
       82 
166 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
            end
         
     | 
| 
      
 167 
     | 
    
         
            +
              end # Factory
         
     | 
| 
      
 168 
     | 
    
         
            +
            end # Rfm
         
     | 
| 
         @@ -0,0 +1,94 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Rfm
         
     | 
| 
      
 2 
     | 
    
         
            +
            	module XmlParser # @private :nodoc: all
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            		extend Config
         
     | 
| 
      
 5 
     | 
    
         
            +
            		config :parent=>'Rfm::Config'
         
     | 
| 
      
 6 
     | 
    
         
            +
            		
         
     | 
| 
      
 7 
     | 
    
         
            +
            		extend self
         
     | 
| 
      
 8 
     | 
    
         
            +
            		
         
     | 
| 
      
 9 
     | 
    
         
            +
            		# Backend configurations
         
     | 
| 
      
 10 
     | 
    
         
            +
            		BACKENDS = ActiveSupport::OrderedHash.new
         
     | 
| 
      
 11 
     | 
    
         
            +
            		
         
     | 
| 
      
 12 
     | 
    
         
            +
            		BACKENDS[:jdom]					= {:require=>'jdom',			:class =>	'JDOM'}
         
     | 
| 
      
 13 
     | 
    
         
            +
            		BACKENDS[:libxml]				= {:require=>'libxml',		:class =>	'LibXML'}
         
     | 
| 
      
 14 
     | 
    
         
            +
            		BACKENDS[:libxmlsax]		= {:require=>'libxml',		:class =>	'LibXMLSAX'}
         
     | 
| 
      
 15 
     | 
    
         
            +
            		BACKENDS[:nokogirisax]	= {:require=>'nokogiri',	:class =>	proc{ActiveSupport::VERSION; 'NokogiriSAX'}}
         
     | 
| 
      
 16 
     | 
    
         
            +
            		BACKENDS[:nokogiri]			= {:require=>'nokogiri',	:class =>	'Nokogiri'}
         
     | 
| 
      
 17 
     | 
    
         
            +
            		BACKENDS[:hpricot]			= {:require=>'hpricot',	  :class =>	proc{
         
     | 
| 
      
 18 
     | 
    
         
            +
            																# Hpricot module is part of Rfm, not XmlMini,
         
     | 
| 
      
 19 
     | 
    
         
            +
            																# and needs to be handed manually to XmlMini.
         
     | 
| 
      
 20 
     | 
    
         
            +
            																require File.join(File.dirname(__FILE__), '../xml_mini/hpricot.rb')
         
     | 
| 
      
 21 
     | 
    
         
            +
            																ActiveSupport::XmlMini_Hpricot}}
         
     | 
| 
      
 22 
     | 
    
         
            +
            		BACKENDS[:rexml]				= {:require=>'rexml/document',	:class=>'REXML'}
         
     | 
| 
      
 23 
     | 
    
         
            +
            		
         
     | 
| 
      
 24 
     | 
    
         
            +
            		
         
     | 
| 
      
 25 
     | 
    
         
            +
            		# Main parsing method.
         
     | 
| 
      
 26 
     | 
    
         
            +
            		# Options
         
     | 
| 
      
 27 
     | 
    
         
            +
            		#		:namespace => false   # strip out namespace (default)
         
     | 
| 
      
 28 
     | 
    
         
            +
            		#		:parser    => :libxml, :libxmlsax, :nokogirisax, :nokogiri, :hpricot, :rexml
         
     | 
| 
      
 29 
     | 
    
         
            +
            		#		:parser    => CustomParsingModule  # see ActiveSupport::XmlMini
         
     | 
| 
      
 30 
     | 
    
         
            +
            		def new(string_or_file, opts={})
         
     | 
| 
      
 31 
     | 
    
         
            +
            			string_or_file.gsub!(/xmlns=\"[^\"]*\"/,'') if (string_or_file.class == String and opts[:namespace] == false)
         
     | 
| 
      
 32 
     | 
    
         
            +
            			unless opts[:parser] and get_backend_from_hash(opts[:parser]).to_s != self.backend.to_s
         
     | 
| 
      
 33 
     | 
    
         
            +
            				warn "XmlParser default: #{ActiveSupport::XmlMini.backend.to_s}" if get_config[:log_parser] == true
         
     | 
| 
      
 34 
     | 
    
         
            +
            				ActiveSupport::XmlMini.parse(string_or_file)
         
     | 
| 
      
 35 
     | 
    
         
            +
            			else
         
     | 
| 
      
 36 
     | 
    
         
            +
            				warn "XmlParser backend: #{get_backend_from_hash(opts[:parser]).to_s}" if get_config[:log_parser] == true
         
     | 
| 
      
 37 
     | 
    
         
            +
            				ActiveSupport::XmlMini.with_backend(get_backend_from_hash(opts[:parser])) {ActiveSupport::XmlMini.parse(string_or_file)}
         
     | 
| 
      
 38 
     | 
    
         
            +
            			end
         
     | 
| 
      
 39 
     | 
    
         
            +
            		end
         
     | 
| 
      
 40 
     | 
    
         
            +
            				
         
     | 
| 
      
 41 
     | 
    
         
            +
            		# Shortcut to XmlMini config getter.
         
     | 
| 
      
 42 
     | 
    
         
            +
            		# If a parameter is passed, it will be used to get the local backend description
         
     | 
| 
      
 43 
     | 
    
         
            +
            		# from the BACKENDS hash, instead of the XmlMini backend.
         
     | 
| 
      
 44 
     | 
    
         
            +
            		def backend(name=nil)
         
     | 
| 
      
 45 
     | 
    
         
            +
            			return ActiveSupport::XmlMini.backend unless name
         
     | 
| 
      
 46 
     | 
    
         
            +
            			get_backend_from_hash(name)
         
     | 
| 
      
 47 
     | 
    
         
            +
            		end
         
     | 
| 
      
 48 
     | 
    
         
            +
            		
         
     | 
| 
      
 49 
     | 
    
         
            +
            		# Shortcut to XmlMini config setter.
         
     | 
| 
      
 50 
     | 
    
         
            +
            		def backend=(name)
         
     | 
| 
      
 51 
     | 
    
         
            +
            			if name.is_a? Symbol
         
     | 
| 
      
 52 
     | 
    
         
            +
            				set_backend_via_hash(name)
         
     | 
| 
      
 53 
     | 
    
         
            +
            			else
         
     | 
| 
      
 54 
     | 
    
         
            +
            				ActiveSupport::XmlMini.backend = name
         
     | 
| 
      
 55 
     | 
    
         
            +
            			end
         
     | 
| 
      
 56 
     | 
    
         
            +
            		end
         
     | 
| 
      
 57 
     | 
    
         
            +
            		
         
     | 
| 
      
 58 
     | 
    
         
            +
            	private
         
     | 
| 
      
 59 
     | 
    
         
            +
            		
         
     | 
| 
      
 60 
     | 
    
         
            +
            		# Given name, return backend config from BACKENDS, including any preloading.
         
     | 
| 
      
 61 
     | 
    
         
            +
            		# Will raise LoadError if can't load backend.
         
     | 
| 
      
 62 
     | 
    
         
            +
            		def get_backend_from_hash(name)
         
     | 
| 
      
 63 
     | 
    
         
            +
            				backend_hash = BACKENDS[name.to_sym]
         
     | 
| 
      
 64 
     | 
    
         
            +
            				require backend_hash[:require]
         
     | 
| 
      
 65 
     | 
    
         
            +
            				backend_hash[:class].is_a?(Proc) ? backend_hash[:class].call : backend_hash[:class]
         
     | 
| 
      
 66 
     | 
    
         
            +
            		end
         
     | 
| 
      
 67 
     | 
    
         
            +
            		
         
     | 
| 
      
 68 
     | 
    
         
            +
            		# Set XmlMini backend, given symbol matching one of the BACKENDS.
         
     | 
| 
      
 69 
     | 
    
         
            +
            		def set_backend_via_hash(name)
         
     | 
| 
      
 70 
     | 
    
         
            +
            			ActiveSupport::XmlMini.backend = get_backend_from_hash(name)
         
     | 
| 
      
 71 
     | 
    
         
            +
            		end
         
     | 
| 
      
 72 
     | 
    
         
            +
            		
         
     | 
| 
      
 73 
     | 
    
         
            +
            		# Select the best backend from BACKENDS, returns backend config.
         
     | 
| 
      
 74 
     | 
    
         
            +
            		def decide_backend
         
     | 
| 
      
 75 
     | 
    
         
            +
            			string_or_class = catch(:done) do
         
     | 
| 
      
 76 
     | 
    
         
            +
            				BACKENDS.keys.each do |name|
         
     | 
| 
      
 77 
     | 
    
         
            +
            					begin
         
     | 
| 
      
 78 
     | 
    
         
            +
            						result = get_backend_from_hash name
         
     | 
| 
      
 79 
     | 
    
         
            +
            						throw(:done, result)
         
     | 
| 
      
 80 
     | 
    
         
            +
            					rescue LoadError, StandardError
         
     | 
| 
      
 81 
     | 
    
         
            +
            					end
         
     | 
| 
      
 82 
     | 
    
         
            +
            				end
         
     | 
| 
      
 83 
     | 
    
         
            +
            			end
         
     | 
| 
      
 84 
     | 
    
         
            +
            		end
         
     | 
| 
      
 85 
     | 
    
         
            +
            				
         
     | 
| 
      
 86 
     | 
    
         
            +
            		# Set XmlMini backend when this file loads.
         
     | 
| 
      
 87 
     | 
    
         
            +
            		begin
         
     | 
| 
      
 88 
     | 
    
         
            +
            			self.backend = get_backend_from_hash(get_config[:parser])
         
     | 
| 
      
 89 
     | 
    
         
            +
            		rescue
         
     | 
| 
      
 90 
     | 
    
         
            +
            			self.backend = decide_backend
         
     | 
| 
      
 91 
     | 
    
         
            +
            		end
         
     | 
| 
      
 92 
     | 
    
         
            +
            		
         
     | 
| 
      
 93 
     | 
    
         
            +
            	end # XmlParser
         
     | 
| 
      
 94 
     | 
    
         
            +
            end # Rfm
         
     |