class GetConnector

Implements communication with getconnectors

Public Class Methods

new(name) click to toggle source

Constructor, takes the name of the connector

# File lib/afasgem/getconnector.rb, line 5
def initialize(name)
        @connectorname = name
        @filters = []
        if Afasgem::debug
                # Build a debug client if the debug flag is set
                @client = Savon.client(
                        wsdl: Afasgem::getconnector_url,
                        log: true,
                        log_level: :debug,
                        pretty_print_xml: true
                )
        else
                # Build a normal client otherwise
                @client = Savon.client(wsdl: Afasgem::getconnector_url)
        end
end

Public Instance Methods

add_filter(field, operator, value = nil) click to toggle source

Adds a filter to the current filter list Provides a fluent interface

# File lib/afasgem/getconnector.rb, line 94
def add_filter(field, operator, value = nil)
        if @filters.size == 0
                @filters.push([])
        end

        # Only the EMPTY and NOT_EMPTY filters should accept a nil value
        if !value
                unless operator == FilterOperators::EMPTY || operator == FilterOperators::NOT_EMPTY
                        raise ArgumentError.new('Value can only be empty when using FilterOperator::EMPTY or FilterOperator::NOT_EMPTY')
                end
        end
        @filters.last.push({field: field, operator: operator, value: value})
        return self
end
add_or() click to toggle source

Adds an OR to the current filter list Provides a fluent interface

# File lib/afasgem/getconnector.rb, line 111
def add_or
        @filters.push([]) if @filters.last && @filters.last.size > 0
        return self
end
clear_filters() click to toggle source

Clears the filters in place Provides a fluent interface

# File lib/afasgem/getconnector.rb, line 118
def clear_filters
        @filters = []
        return self
end
execute() click to toggle source

execute the request Provides a fluent interface

# File lib/afasgem/getconnector.rb, line 69
def execute
        result = execute_request(get_resultcount, @skip)

        @data_xml = result[0]
        @result = result[1]
        return self
end
get_all_results() click to toggle source

Fetches all results Data is not cached

# File lib/afasgem/getconnector.rb, line 79
def get_all_results
        result_array = []
        skip = 0
        take = 1000
        loop do
                current_result = get_data_from_result(execute_request(take, skip)[1])
                result_array.concat(current_result)
                skip = skip + take
                break if current_result.size != take
        end
        return result_array
end
get_data() click to toggle source

Returns the actual data as a hash

# File lib/afasgem/getconnector.rb, line 131
def get_data
        execute unless @result
        return get_data_from_result(@result)
end
get_data_xml() click to toggle source

Returns the raw xml

# File lib/afasgem/getconnector.rb, line 137
def get_data_xml
        execute unless @data_xml
        return @data_xml
end
get_result() click to toggle source

Returns the result as a hash This includes the type definition

# File lib/afasgem/getconnector.rb, line 125
def get_result
        execute unless @result
        return @result
end
next() click to toggle source

Fetch the next page Provides a fluent interface

# File lib/afasgem/getconnector.rb, line 52
def next
        @skip = (@skip || 0) + get_resultcount
        @result = nil
        return self
end
page(number) click to toggle source

Set the page we want to fetch 1 indexed (i.e. page 1 will fetch result 0 to x) Provides a fluent interface

# File lib/afasgem/getconnector.rb, line 43
def page(number)
        fail ArgumentError.new("Page number cannot be lower than 1, #{number} given") unless number > 0
        @result = nil
        @skip = (number - 1) * get_resultcount
        return self
end
previous() click to toggle source

Fetch the previous page Provides a fluent interface

# File lib/afasgem/getconnector.rb, line 60
def previous
        @result = nil
        @skip = (@skip || 0) - get_resultcount
        @skip = [0, @skip].max
        return self
end
skip(count) click to toggle source

Set the number of results we want to skip Provides a fluent interface

# File lib/afasgem/getconnector.rb, line 33
def skip(count)
        fail ArgumentError.new("Count cannot be lower than 1, #{count} given") unless count > 0
        @result = nil
        @skip = count
        return self
end
take(count) click to toggle source

Set the number of results we want to have Provides a fluent interface

# File lib/afasgem/getconnector.rb, line 24
def take(count)
        fail ArgumentError.new("Count cannot be lower than 1, #{count} given") unless count > 0
        @result = nil
        @resultcount = count
        return self
end

Private Instance Methods

execute_request(take, skip = nil) click to toggle source

Actually fires the request

# File lib/afasgem/getconnector.rb, line 145
def execute_request(take, skip = nil)
        message = {
                token: Afasgem.get_token,
                connectorId: @connectorname,
                take: take
        }

        message[:skip] = skip if skip
        filter_string = get_filter_string
        message[:filtersXml] = filter_string if filter_string

        resp = @client.call(:get_data, message: message)
        xml_string = resp.hash[:envelope][:body][:get_data_response][:get_data_result]
        return [xml_string, from_xml(xml_string)]
end
from_xml(xml_io) click to toggle source

Source of code below: gist.github.com/huy/819999

# File lib/afasgem/getconnector.rb, line 230
def from_xml(xml_io)
        begin
                result = Nokogiri::XML(xml_io)
                return { result.root.name.to_sym => xml_node_to_hash(result.root)}
        rescue Exception => e
                # raise your custom exception here
        end
end
get_data_from_result(result) click to toggle source

Returns the actual rows from a parsed response hash

# File lib/afasgem/getconnector.rb, line 221
def get_data_from_result(result)
        val = result[:AfasGetConnector][@connectorname.to_sym]
        val = [] if val.nil?
        val = [val] unless val.is_a?(Array)
        return val
end
get_filter_string() click to toggle source

Returns the filter xml in string format

# File lib/afasgem/getconnector.rb, line 162
def get_filter_string
        return nil if @filters.size == 0
        filters = []

        # Loop over each filtergroup
        # All conditions in a filtergroup are combined using AND
        # All filtergroups are combined using OR
        @filters.each_with_index do |filter, index|
                fields = []

                # Loop over all conditions in a filter group
                filter.each do |condition|
                        field = condition[:field]
                        operator = condition[:operator]
                        value = condition[:value]

                        # Some filters operate on strings and need wildcards
                        # Transform value if needed
                        case operator
                                when FilterOperators::LIKE
                                        value = "%#{value}%"
                                when FilterOperators::STARTS_WITH
                                        value = "#{value}%"
                                when FilterOperators::NOT_LIKE
                                        value = "%#{value}%"
                                when FilterOperators::NOT_STARTS_WITH
                                        value = "#{value}%"
                                when FilterOperators::ENDS_WITH
                                        value = "%#{value}"
                                when FilterOperators::NOT_ENDS_WITH
                                        value = "%#{value}"
                                when FilterOperators::EMPTY
                                        # EMPTY and NOT_EMPTY operators require the filter to be in a different format
                                        # This because they take no value
                                        fields.push("<Field FieldId=\"#{field}\" OperatorType=\"#{operator}\" />")
                                        next
                                when FilterOperators::NOT_EMPTY
                                        fields.push("<Field FieldId=\"#{field}\" OperatorType=\"#{operator}\" />")
                                        next
                        end

                        # Add this filterstring to filters
                        fields.push("<Field FieldId=\"#{field}\" OperatorType=\"#{operator}\">#{value}</Field>")
                end

                # Make sure all filtergroups are OR'ed and add them
                filters.push("<Filter FilterId=\"Filter #{index}\">#{fields.join}</Filter>")
        end

        # Return the whole filterstring
        return "<Filters>#{filters.join}</Filters>"
end
get_resultcount() click to toggle source

Returns the number of results we want to fetch

# File lib/afasgem/getconnector.rb, line 216
def get_resultcount
        return @resultcount || Afasgem.default_results
end
xml_node_to_hash(node) click to toggle source
# File lib/afasgem/getconnector.rb, line 239
def xml_node_to_hash(node)
        # If we are at the root of the document, start the hash
        if node.element?
                result_hash = {}
                if node.attributes != {}
                        attributes = {}
                        node.attributes.keys.each do |key|
                                attributes[node.attributes[key].name.to_sym] = node.attributes[key].value
                        end
                end
                if node.children.size > 0
                        node.children.each do |child|
                                result = xml_node_to_hash(child)

                                if child.name == "text"
                                        unless child.next_sibling || child.previous_sibling
                                                return result unless attributes
                                                result_hash[child.name.to_sym] = result
                                        end
                                elsif result_hash[child.name.to_sym]

                                        if result_hash[child.name.to_sym].is_a?(Object::Array)
                                                result_hash[child.name.to_sym] << result
                                        else
                                                result_hash[child.name.to_sym] = [result_hash[child.name.to_sym]] << result
                                        end
                                else
                                        result_hash[child.name.to_sym] = result
                                end
                        end
                        if attributes
                                #add code to remove non-data attributes e.g. xml schema, namespace here
                                #if there is a collision then node content supersets attributes
                                result_hash = attributes.merge(result_hash)
                        end
                        return result_hash
                else
                        return attributes
                end
        else
                return node.content.to_s
        end
end