sqlcached_client 1.0.0 → 1.1.0
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.
- checksums.yaml +4 -4
 - data/lib/sqlcached_client/attachment.rb +54 -0
 - data/lib/sqlcached_client/attachments.rb +36 -0
 - data/lib/sqlcached_client/entity.rb +32 -8
 - data/lib/sqlcached_client/proxy_object.rb +29 -0
 - data/lib/sqlcached_client/resultset.rb +32 -3
 - data/lib/sqlcached_client/server.rb +36 -22
 - data/lib/sqlcached_client/server_responses/query_response.rb +52 -0
 - data/lib/sqlcached_client/version.rb +1 -1
 - data/spec/sqlcached_client/attachment_spec.rb +68 -0
 - data/spec/sqlcached_client/attachments_spec.rb +19 -0
 - data/spec/sqlcached_client/entity_spec.rb +7 -1
 - data/spec/sqlcached_client/proxy_object_spec.rb +35 -0
 - data/spec/sqlcached_client/resultset_spec.rb +39 -2
 - data/spec/sqlcached_client/server_responses/query_response_spec.rb +79 -0
 - data/spec/sqlcached_client/server_spec.rb +5 -30
 - metadata +14 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: e1f725ac30395fee0332b228f2f7afba9a8e3f63
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 6c8f3618babaf1f18b1295d75bb86a89c84007ca
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e7759cc739a2e3d14bc63c294b84cc1096ed7c97f877e4e86210d3e792bfc61e95cab515b7a7a0362e87aaab382cad539305e5caf0eaf0beacdd8aeb860a848b
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 26d535fd6114978514c5b726755bdfd69a30458955a31259ccfc4f86d6baf7dc1dde767f501e392c91cad7e7ffb62077f03e6eaba14e9705fb7998bb2bce9915
         
     | 
| 
         @@ -0,0 +1,54 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/core_ext/hash'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module SqlcachedClient
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Attachment
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                PREDICATES = ['=', '<=', '>']
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :name, :conditions
         
     | 
| 
      
 9 
     | 
    
         
            +
                attr_accessor :content
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                # @param conditions [Hash] { var_1: 'value 1', var_2: 'value 2' }
         
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(name, conditions, content)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @conditions = conditions.with_indifferent_access
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @content = content
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  attr_reader :variables
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def add_variable(variable_name, predicate)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    raise "Invalid predicate" if !PREDICATES.include?(predicate)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @variables = [] if @variables.nil?
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @variables << OpenStruct.new(name: variable_name, predicate: predicate)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  alias_method :depends_on, :add_variable
         
     | 
| 
      
 29 
     | 
    
         
            +
                end # class << self
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def variables
         
     | 
| 
      
 32 
     | 
    
         
            +
                  self.class.variables
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def to_query_format
         
     | 
| 
      
 36 
     | 
    
         
            +
                  {
         
     | 
| 
      
 37 
     | 
    
         
            +
                    name: name,
         
     | 
| 
      
 38 
     | 
    
         
            +
                    condition_values: Hash[
         
     | 
| 
      
 39 
     | 
    
         
            +
                      variables.map { |v| [v.name, conditions[v.name]] }
         
     | 
| 
      
 40 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 41 
     | 
    
         
            +
                  }
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def to_save_format
         
     | 
| 
      
 45 
     | 
    
         
            +
                  {
         
     | 
| 
      
 46 
     | 
    
         
            +
                    name: name,
         
     | 
| 
      
 47 
     | 
    
         
            +
                    attachment: content,
         
     | 
| 
      
 48 
     | 
    
         
            +
                    conditions: variables.map do |v|
         
     | 
| 
      
 49 
     | 
    
         
            +
                      "#{v.name} #{v.predicate} #{conditions[v.name]}"
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  }
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sqlcached_client/attachment'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module SqlcachedClient
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Attachments
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                module ClassMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def has_attachment(name, &block)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @attachment_classes ||= {}
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @attachment_classes[name] =
         
     | 
| 
      
 11 
     | 
    
         
            +
                      Class.new(Attachment) do
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                        @attachment_name = name
         
     | 
| 
      
 14 
     | 
    
         
            +
                        class << self
         
     | 
| 
      
 15 
     | 
    
         
            +
                          attr_reader :attachment_name
         
     | 
| 
      
 16 
     | 
    
         
            +
                        end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                        def initialize(conditions, content)
         
     | 
| 
      
 19 
     | 
    
         
            +
                          super(self.class.attachment_name, conditions, content)
         
     | 
| 
      
 20 
     | 
    
         
            +
                        end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                        instance_exec(&block)
         
     | 
| 
      
 23 
     | 
    
         
            +
                      end
         
     | 
| 
      
 24 
     | 
    
         
            +
                    attr_accessor(name)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def build_attachments(name, conditions, size)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    size.times.map { @attachment_classes[name].new(conditions, nil) }
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                end # module ClassMethods
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def self.included(base)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  base.extend ClassMethods
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -2,6 +2,7 @@ require 'sqlcached_client/resultset' 
     | 
|
| 
       2 
2 
     | 
    
         
             
            require 'sqlcached_client/server'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'sqlcached_client/arel'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'sqlcached_client/tree_visitor'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'sqlcached_client/proxy_object'
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module SqlcachedClient
         
     | 
| 
       7 
8 
     | 
    
         
             
              class Entity
         
     | 
| 
         @@ -85,6 +86,19 @@ module SqlcachedClient 
     | 
|
| 
       85 
86 
     | 
    
         
             
                    server.session(&block)
         
     | 
| 
       86 
87 
     | 
    
         
             
                  end
         
     | 
| 
       87 
88 
     | 
    
         | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  def transaction(&block)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    proxy = ProxyObject.new(self)
         
     | 
| 
      
 92 
     | 
    
         
            +
                    srv_local = server
         
     | 
| 
      
 93 
     | 
    
         
            +
                    session = server.get_session
         
     | 
| 
      
 94 
     | 
    
         
            +
                    proxy.plug_method(:server_session) do |server_session_block|
         
     | 
| 
      
 95 
     | 
    
         
            +
                      instance_exec(srv_local, session, &server_session_block)
         
     | 
| 
      
 96 
     | 
    
         
            +
                    end
         
     | 
| 
      
 97 
     | 
    
         
            +
                    result = proxy.execute(srv_local, session, &block)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    session.finish
         
     | 
| 
      
 99 
     | 
    
         
            +
                    result
         
     | 
| 
      
 100 
     | 
    
         
            +
                  end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
       88 
102 
     | 
    
         
             
                  # Runs the entity query with the provided parameters
         
     | 
| 
       89 
103 
     | 
    
         
             
                  # @return [Resultset]
         
     | 
| 
       90 
104 
     | 
    
         
             
                  def where(params, dry_run = false)
         
     | 
| 
         @@ -102,14 +116,14 @@ module SqlcachedClient 
     | 
|
| 
       102 
116 
     | 
    
         
             
                    if dry_run
         
     | 
| 
       103 
117 
     | 
    
         
             
                      request
         
     | 
| 
       104 
118 
     | 
    
         
             
                    else
         
     | 
| 
       105 
     | 
    
         
            -
                       
     | 
| 
       106 
     | 
    
         
            -
                         
     | 
| 
      
 119 
     | 
    
         
            +
                      server_resp =
         
     | 
| 
      
 120 
     | 
    
         
            +
                        server_session do |server, session|
         
     | 
| 
       107 
121 
     | 
    
         
             
                          server.run_query(session, server.build_request(
         
     | 
| 
       108 
122 
     | 
    
         
             
                            request.is_a?(Array) ? request : [request]
         
     | 
| 
       109 
123 
     | 
    
         
             
                          ))
         
     | 
| 
       110 
124 
     | 
    
         
             
                        end
         
     | 
| 
       111 
     | 
    
         
            -
                       
     | 
| 
       112 
     | 
    
         
            -
                      Resultset.new(self,  
     | 
| 
      
 125 
     | 
    
         
            +
                      server_resp.flatten!(1) if server_resp.is_array?
         
     | 
| 
      
 126 
     | 
    
         
            +
                      Resultset.new(self, server_resp)
         
     | 
| 
       113 
127 
     | 
    
         
             
                    end
         
     | 
| 
       114 
128 
     | 
    
         
             
                  end
         
     | 
| 
       115 
129 
     | 
    
         | 
| 
         @@ -272,14 +286,24 @@ module SqlcachedClient 
     | 
|
| 
       272 
286 
     | 
    
         
             
                  # Like 'where' but loads every associated entity recursively at any level,
         
     | 
| 
       273 
287 
     | 
    
         
             
                  #   with only one interaction with the server
         
     | 
| 
       274 
288 
     | 
    
         
             
                  # @param root_conditions [Array]
         
     | 
| 
       275 
     | 
    
         
            -
                  def load_tree(root_conditions 
     | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
      
 289 
     | 
    
         
            +
                  def load_tree(root_conditions, attachment_name = nil,
         
     | 
| 
      
 290 
     | 
    
         
            +
                      attachment_conditions = nil)
         
     | 
| 
      
 291 
     | 
    
         
            +
                    attachments =
         
     | 
| 
      
 292 
     | 
    
         
            +
                      if attachment_name.present?
         
     | 
| 
      
 293 
     | 
    
         
            +
                        build_attachments(attachment_name, attachment_conditions,
         
     | 
| 
      
 294 
     | 
    
         
            +
                          root_conditions.size)
         
     | 
| 
      
 295 
     | 
    
         
            +
                      else
         
     | 
| 
      
 296 
     | 
    
         
            +
                        nil
         
     | 
| 
      
 297 
     | 
    
         
            +
                      end
         
     | 
| 
      
 298 
     | 
    
         
            +
                    server_session do |server, session|
         
     | 
| 
       277 
299 
     | 
    
         
             
                      Resultset.new(
         
     | 
| 
       278 
300 
     | 
    
         
             
                        self,
         
     | 
| 
       279 
301 
     | 
    
         
             
                        server.run_query(
         
     | 
| 
       280 
302 
     | 
    
         
             
                          session,
         
     | 
| 
       281 
     | 
    
         
            -
                          server.build_tree_request(build_query_tree, root_conditions 
     | 
| 
       282 
     | 
    
         
            -
             
     | 
| 
      
 303 
     | 
    
         
            +
                          server.build_tree_request(build_query_tree, root_conditions,
         
     | 
| 
      
 304 
     | 
    
         
            +
                            attachments)
         
     | 
| 
      
 305 
     | 
    
         
            +
                        ),
         
     | 
| 
      
 306 
     | 
    
         
            +
                        attachments
         
     | 
| 
       283 
307 
     | 
    
         
             
                      )
         
     | 
| 
       284 
308 
     | 
    
         
             
                    end
         
     | 
| 
       285 
309 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SqlcachedClient
         
     | 
| 
      
 2 
     | 
    
         
            +
              class ProxyObject < BasicObject
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                def initialize(context)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  @context = context
         
     | 
| 
      
 6 
     | 
    
         
            +
                end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def method_missing(symbol, *args)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @context.send(symbol, *args)
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def execute(*args, &block)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  instance_exec(*args, &block)
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def plug_method(method_name, &method_body)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  memoize_var = "@m_#{method_name}"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  instance_variable_set(memoize_var, method_body)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  eval(
         
     | 
| 
      
 20 
     | 
    
         
            +
                    <<-RUBY
         
     | 
| 
      
 21 
     | 
    
         
            +
                      def self.#{method_name}(*args, &block)
         
     | 
| 
      
 22 
     | 
    
         
            +
                        instance_exec(*args, block, &#{memoize_var})
         
     | 
| 
      
 23 
     | 
    
         
            +
                      end
         
     | 
| 
      
 24 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 25 
     | 
    
         
            +
                  )
         
     | 
| 
      
 26 
     | 
    
         
            +
                  method_name.to_sym
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -5,10 +5,13 @@ module SqlcachedClient 
     | 
|
| 
       5 
5 
     | 
    
         
             
                attr_reader :entity_class, :entities, :count
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                # @param entity_class [Class]
         
     | 
| 
       8 
     | 
    
         
            -
                # @param  
     | 
| 
       9 
     | 
    
         
            -
                def initialize(entity_class,  
     | 
| 
      
 8 
     | 
    
         
            +
                # @param data [Array] or [ServerResponse]
         
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(entity_class, data, attachments = nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # set entity class
         
     | 
| 
       10 
11 
     | 
    
         
             
                  @entity_class = entity_class
         
     | 
| 
       11 
     | 
    
         
            -
                   
     | 
| 
      
 12 
     | 
    
         
            +
                  # build the entities
         
     | 
| 
      
 13 
     | 
    
         
            +
                  ents = data.respond_to?(:entities) ? data.entities : data
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @entities = (ents || []).map do |item|
         
     | 
| 
       12 
15 
     | 
    
         
             
                    if item.is_a?(Hash)
         
     | 
| 
       13 
16 
     | 
    
         
             
                      entity_class.new(item)
         
     | 
| 
       14 
17 
     | 
    
         
             
                    elsif item.is_a?(entity_class)
         
     | 
| 
         @@ -17,7 +20,10 @@ module SqlcachedClient 
     | 
|
| 
       17 
20 
     | 
    
         
             
                      raise "Cannot handle: #{item.inspect}"
         
     | 
| 
       18 
21 
     | 
    
         
             
                    end
         
     | 
| 
       19 
22 
     | 
    
         
             
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # record collection size
         
     | 
| 
       20 
24 
     | 
    
         
             
                  @count = @entities.size
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # set up attachments
         
     | 
| 
      
 26 
     | 
    
         
            +
                  set_entities_attachments(@entities, attachments, data.try(:attachments))
         
     | 
| 
       21 
27 
     | 
    
         
             
                end
         
     | 
| 
       22 
28 
     | 
    
         | 
| 
       23 
29 
     | 
    
         
             
                class << self
         
     | 
| 
         @@ -69,5 +75,28 @@ module SqlcachedClient 
     | 
|
| 
       69 
75 
     | 
    
         
             
                    entity.get_association_requests
         
     | 
| 
       70 
76 
     | 
    
         
             
                  end
         
     | 
| 
       71 
77 
     | 
    
         
             
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                def set_entities_attachments(entities, attachments, contents)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  if attachments.is_a?(Array) && contents.is_a?(Array)
         
     | 
| 
      
 81 
     | 
    
         
            +
                    entities.each_with_index do |entity, i|
         
     | 
| 
      
 82 
     | 
    
         
            +
                      attachment = attachments[i]
         
     | 
| 
      
 83 
     | 
    
         
            +
                      entity.send("#{attachment.name}=", attachment)
         
     | 
| 
      
 84 
     | 
    
         
            +
                      attachment.content = contents[i] if attachment.respond_to?(:content=)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def store_attachments(attachment_name, server, session)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  entities_with_a = entities.select do |entity|
         
     | 
| 
      
 91 
     | 
    
         
            +
                    !entity.send(attachment_name).nil?
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                  server.store_attachments(
         
     | 
| 
      
 94 
     | 
    
         
            +
                    session,
         
     | 
| 
      
 95 
     | 
    
         
            +
                    server.build_store_attachments_request(
         
     | 
| 
      
 96 
     | 
    
         
            +
                      entities_with_a.map { |e| e.attributes },
         
     | 
| 
      
 97 
     | 
    
         
            +
                      entities_with_a.map { |e| e.send(attachment_name).to_save_format }
         
     | 
| 
      
 98 
     | 
    
         
            +
                    )
         
     | 
| 
      
 99 
     | 
    
         
            +
                  )
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
       72 
101 
     | 
    
         
             
              end
         
     | 
| 
       73 
102 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'uri'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'net/http'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'json'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'sqlcached_client/server_responses/query_response'
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module SqlcachedClient
         
     | 
| 
       6 
7 
     | 
    
         
             
              class Server
         
     | 
| 
         @@ -12,37 +13,32 @@ module SqlcachedClient 
     | 
|
| 
       12 
13 
     | 
    
         
             
                  @port = config[:port]
         
     | 
| 
       13 
14 
     | 
    
         
             
                end
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
                # @return [ServerResponses::QueryResponse]
         
     | 
| 
       16 
17 
     | 
    
         
             
                def run_query(session, http_req_body)
         
     | 
| 
       17 
18 
     | 
    
         
             
                  req = Net::HTTP::Post.new(data_batch_url)
         
     | 
| 
       18 
19 
     | 
    
         
             
                  req.set_content_type('application/json')
         
     | 
| 
       19 
20 
     | 
    
         
             
                  req.body = http_req_body.to_json
         
     | 
| 
       20 
21 
     | 
    
         
             
                  resp = session.request(req)
         
     | 
| 
       21 
     | 
    
         
            -
                   
     | 
| 
       22 
     | 
    
         
            -
                     
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                     
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
                  resp_body =
         
     | 
| 
      
 23 
     | 
    
         
            +
                    if (resp['Content-Type'] || '') =~ /application\/json/
         
     | 
| 
      
 24 
     | 
    
         
            +
                      JSON.parse(resp.body)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    else
         
     | 
| 
      
 26 
     | 
    
         
            +
                      resp.body
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
       26 
28 
     | 
    
         
             
                  if 200 == resp.code.to_i
         
     | 
| 
       27 
     | 
    
         
            -
                    resp_body
         
     | 
| 
      
 29 
     | 
    
         
            +
                    ServerResponses::QueryResponse.new(resp_body)
         
     | 
| 
       28 
30 
     | 
    
         
             
                  else
         
     | 
| 
       29 
31 
     | 
    
         
             
                    raise "Got HTTP response #{resp.code} from server - #{resp_body.inspect}"
         
     | 
| 
       30 
32 
     | 
    
         
             
                  end
         
     | 
| 
       31 
33 
     | 
    
         
             
                end
         
     | 
| 
       32 
34 
     | 
    
         | 
| 
       33 
35 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                def  
     | 
| 
       35 
     | 
    
         
            -
                   
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                   
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                    else
         
     | 
| 
       41 
     | 
    
         
            -
                      resultset
         
     | 
| 
       42 
     | 
    
         
            -
                    end
         
     | 
| 
       43 
     | 
    
         
            -
                  else
         
     | 
| 
       44 
     | 
    
         
            -
                    body
         
     | 
| 
       45 
     | 
    
         
            -
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                def store_attachments(session, http_req_body)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  req = Net::HTTP::Post.new(store_attachments_url)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  req.set_content_type('application/json')
         
     | 
| 
      
 39 
     | 
    
         
            +
                  req.body = http_req_body.to_json
         
     | 
| 
      
 40 
     | 
    
         
            +
                  resp = session.request(req)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  201 == resp.code.to_i || raise("Failed to save attachments - server answered with #{resp.body.inspect}")
         
     | 
| 
       46 
42 
     | 
    
         
             
                end
         
     | 
| 
       47 
43 
     | 
    
         | 
| 
       48 
44 
     | 
    
         
             
                # Builds a 'standard' request body
         
     | 
| 
         @@ -56,8 +52,12 @@ module SqlcachedClient 
     | 
|
| 
       56 
52 
     | 
    
         
             
                # @param tree [Hash]
         
     | 
| 
       57 
53 
     | 
    
         
             
                # @param root_parameters [Array] a vector of actual condition parameters
         
     | 
| 
       58 
54 
     | 
    
         
             
                #   for the root query
         
     | 
| 
       59 
     | 
    
         
            -
                def build_tree_request(tree, root_parameters)
         
     | 
| 
       60 
     | 
    
         
            -
                  { tree: tree, root_parameters: root_parameters }
         
     | 
| 
      
 55 
     | 
    
         
            +
                def build_tree_request(tree, root_parameters, attachments = nil)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  h = { tree: tree, root_parameters: root_parameters }
         
     | 
| 
      
 57 
     | 
    
         
            +
                  if !attachments.nil?
         
     | 
| 
      
 58 
     | 
    
         
            +
                    h[:attachments] = attachments.map(&:to_query_format)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
                  h
         
     | 
| 
       61 
61 
     | 
    
         
             
                end
         
     | 
| 
       62 
62 
     | 
    
         | 
| 
       63 
63 
     | 
    
         
             
                # Formats the parameters passed in the way the server expects
         
     | 
| 
         @@ -75,6 +75,14 @@ module SqlcachedClient 
     | 
|
| 
       75 
75 
     | 
    
         
             
                  }
         
     | 
| 
       76 
76 
     | 
    
         
             
                end
         
     | 
| 
       77 
77 
     | 
    
         | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                def build_store_attachments_request(entities, attachments)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  {
         
     | 
| 
      
 81 
     | 
    
         
            +
                    resultset: entities,
         
     | 
| 
      
 82 
     | 
    
         
            +
                    attachments: attachments
         
     | 
| 
      
 83 
     | 
    
         
            +
                  }
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
       78 
86 
     | 
    
         
             
                # @return [Net::HTTP] an http session on the server
         
     | 
| 
       79 
87 
     | 
    
         
             
                def get_session
         
     | 
| 
       80 
88 
     | 
    
         
             
                  url = server_url
         
     | 
| 
         @@ -99,7 +107,13 @@ module SqlcachedClient 
     | 
|
| 
       99 
107 
     | 
    
         | 
| 
       100 
108 
     | 
    
         
             
                def data_batch_url
         
     | 
| 
       101 
109 
     | 
    
         
             
                  url = server_url
         
     | 
| 
       102 
     | 
    
         
            -
                  url.path =  
     | 
| 
      
 110 
     | 
    
         
            +
                  url.path = '/data-batch'
         
     | 
| 
      
 111 
     | 
    
         
            +
                  url
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                def store_attachments_url
         
     | 
| 
      
 115 
     | 
    
         
            +
                  url = server_url
         
     | 
| 
      
 116 
     | 
    
         
            +
                  url.path = '/resultset-attachments'
         
     | 
| 
       103 
117 
     | 
    
         
             
                  url
         
     | 
| 
       104 
118 
     | 
    
         
             
                end
         
     | 
| 
       105 
119 
     | 
    
         
             
              end
         
     | 
| 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SqlcachedClient
         
     | 
| 
      
 2 
     | 
    
         
            +
              module ServerResponses
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                class QueryResponse
         
     | 
| 
      
 5 
     | 
    
         
            +
                  include Enumerable
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_reader :body
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  # @param body [Hash]
         
     | 
| 
      
 10 
     | 
    
         
            +
                  def initialize(body)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @body = body
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def each(&block)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    block ? entities.each(&block) : entities.each
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def attachments
         
     | 
| 
      
 19 
     | 
    
         
            +
                    body.is_a?(Hash) ? body['attachments'] : nil
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def entities
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @entities ||= get_entities(body)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def is_array?
         
     | 
| 
      
 27 
     | 
    
         
            +
                    entities.is_a?(Array)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def flatten!(level = nil)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    entities if @entities.nil?
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @entities.flatten!(level)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                private
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  def get_entities(data)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    if data.is_a?(Array)
         
     | 
| 
      
 39 
     | 
    
         
            +
                      data.map { |item| get_entities(item) }
         
     | 
| 
      
 40 
     | 
    
         
            +
                    elsif data.is_a?(Hash)
         
     | 
| 
      
 41 
     | 
    
         
            +
                      if (resultset = data['resultset']).is_a?(String)
         
     | 
| 
      
 42 
     | 
    
         
            +
                        JSON.parse(resultset)
         
     | 
| 
      
 43 
     | 
    
         
            +
                      else
         
     | 
| 
      
 44 
     | 
    
         
            +
                        resultset
         
     | 
| 
      
 45 
     | 
    
         
            +
                      end
         
     | 
| 
      
 46 
     | 
    
         
            +
                    else
         
     | 
| 
      
 47 
     | 
    
         
            +
                      data
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                end # class QueryResponse
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,68 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sqlcached_client/attachment'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe SqlcachedClient::Attachment do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              let(:described_class) { SqlcachedClient::Attachment }
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              describe :initialize do
         
     | 
| 
      
 8 
     | 
    
         
            +
                it "accepts name, conditions and content" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                  attachment = described_class.new('name', { 'foo' => 'bar'}, 'content')
         
     | 
| 
      
 10 
     | 
    
         
            +
                  expect(attachment.name).to eq('name')
         
     | 
| 
      
 11 
     | 
    
         
            +
                  expect(attachment.conditions).to eq({ 'foo' => 'bar' })
         
     | 
| 
      
 12 
     | 
    
         
            +
                  expect(attachment.content).to eq('content')
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              describe :variables do
         
     | 
| 
      
 17 
     | 
    
         
            +
                it "returns the variables added to the class" do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  attachment = described_class.new(nil, {}, nil)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  allow(described_class).to receive(:variables).and_return('foo')
         
     | 
| 
      
 20 
     | 
    
         
            +
                  expect(attachment.variables).to eq('foo')
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              describe :to_query_format do
         
     | 
| 
      
 25 
     | 
    
         
            +
                it "is an hash with name and condition values" do
         
     | 
| 
      
 26 
     | 
    
         
            +
                  attachment = described_class.new('foo', { v1: 'bar', v2: 'baz'}, nil)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  allow(attachment).to receive(:variables).and_return([
         
     | 
| 
      
 28 
     | 
    
         
            +
                    double(name: 'v1'), double(name: 'v2')
         
     | 
| 
      
 29 
     | 
    
         
            +
                  ])
         
     | 
| 
      
 30 
     | 
    
         
            +
                  expect(attachment.to_query_format).to eq({
         
     | 
| 
      
 31 
     | 
    
         
            +
                    name: 'foo',
         
     | 
| 
      
 32 
     | 
    
         
            +
                    condition_values: {
         
     | 
| 
      
 33 
     | 
    
         
            +
                      'v1' => 'bar', 'v2' => 'baz'
         
     | 
| 
      
 34 
     | 
    
         
            +
                    }
         
     | 
| 
      
 35 
     | 
    
         
            +
                  })
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              describe :to_save_format do
         
     | 
| 
      
 40 
     | 
    
         
            +
                it "is an hash with name, attachment and conditions" do
         
     | 
| 
      
 41 
     | 
    
         
            +
                  attachment = described_class.new('foo', { v1: 'bar', v2: 'baz'},
         
     | 
| 
      
 42 
     | 
    
         
            +
                    'content')
         
     | 
| 
      
 43 
     | 
    
         
            +
                  allow(attachment).to receive(:variables).and_return([
         
     | 
| 
      
 44 
     | 
    
         
            +
                    double(name: 'v1', predicate: '='), double(name: 'v2', predicate: '<=')
         
     | 
| 
      
 45 
     | 
    
         
            +
                  ])
         
     | 
| 
      
 46 
     | 
    
         
            +
                  expect(attachment.to_save_format).to eq({
         
     | 
| 
      
 47 
     | 
    
         
            +
                    name: 'foo',
         
     | 
| 
      
 48 
     | 
    
         
            +
                    attachment: 'content',
         
     | 
| 
      
 49 
     | 
    
         
            +
                    conditions: ['v1 = bar', 'v2 <= baz']
         
     | 
| 
      
 50 
     | 
    
         
            +
                  })
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              describe :add_variable do
         
     | 
| 
      
 55 
     | 
    
         
            +
                it "adds a new variable in the class list" do
         
     | 
| 
      
 56 
     | 
    
         
            +
                  described_class.add_variable('foo', '=')
         
     | 
| 
      
 57 
     | 
    
         
            +
                  v = described_class.variables.first
         
     | 
| 
      
 58 
     | 
    
         
            +
                  expect(v.name).to eq('foo')
         
     | 
| 
      
 59 
     | 
    
         
            +
                  expect(v.predicate).to eq('=')
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                context "if predicate symbol is not allowed" do
         
     | 
| 
      
 63 
     | 
    
         
            +
                  it "raises an exception" do
         
     | 
| 
      
 64 
     | 
    
         
            +
                    expect { described_class.add_variable('foo', 'X') }.to raise_exception
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sqlcached_client/attachments'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe SqlcachedClient::Attachments do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:klass) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                Class.new do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  include SqlcachedClient::Attachments
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  has_attachment :foo do
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              context "after including the module" do
         
     | 
| 
      
 14 
     | 
    
         
            +
                it "add methods 'has_attachment' and 'build_attachments' to the class" do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  expect(klass.respond_to?(:has_attachment)).to eq(true)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  expect(klass.respond_to?(:build_attachments)).to eq(true)
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -154,7 +154,8 @@ describe SqlcachedClient::Entity do 
     | 
|
| 
       154 
154 
     | 
    
         
             
                    entity_class.server(double(
         
     | 
| 
       155 
155 
     | 
    
         
             
                      build_request_item: "this is the request",
         
     | 
| 
       156 
156 
     | 
    
         
             
                      build_request: "request body",
         
     | 
| 
       157 
     | 
    
         
            -
                      session:  
     | 
| 
      
 157 
     | 
    
         
            +
                      session: double(is_array?: false,
         
     | 
| 
      
 158 
     | 
    
         
            +
                        entities: [{ key: "value" }, { key: "value" }])
         
     | 
| 
       158 
159 
     | 
    
         
             
                    ))
         
     | 
| 
       159 
160 
     | 
    
         
             
                    expect(entity_class.server).to receive(:build_request_item).with(
         
     | 
| 
       160 
161 
     | 
    
         
             
                      "foo", "bar", { baz: "biz" }, true)
         
     | 
| 
         @@ -224,4 +225,9 @@ describe SqlcachedClient::Entity do 
     | 
|
| 
       224 
225 
     | 
    
         
             
              describe :build_query_tree do
         
     | 
| 
       225 
226 
     | 
    
         
             
                pending
         
     | 
| 
       226 
227 
     | 
    
         
             
              end
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
              describe :transaction do
         
     | 
| 
      
 231 
     | 
    
         
            +
                pending
         
     | 
| 
      
 232 
     | 
    
         
            +
              end
         
     | 
| 
       227 
233 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sqlcached_client/proxy_object'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe SqlcachedClient::ProxyObject do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:klass) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                Class.new do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def foo
         
     | 
| 
      
 7 
     | 
    
         
            +
                    'bar'
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              it "forwards method calls to the proxied object" do
         
     | 
| 
      
 13 
     | 
    
         
            +
                f = klass.new
         
     | 
| 
      
 14 
     | 
    
         
            +
                p = SqlcachedClient::ProxyObject.new(f)
         
     | 
| 
      
 15 
     | 
    
         
            +
                expect(p.foo).to eq('bar')
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              describe :execute do
         
     | 
| 
      
 19 
     | 
    
         
            +
                it "executes the block provided in the context of the instance" do
         
     | 
| 
      
 20 
     | 
    
         
            +
                  f = klass.new
         
     | 
| 
      
 21 
     | 
    
         
            +
                  p = SqlcachedClient::ProxyObject.new(f)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  expect(p.execute { foo }).to eq('bar')
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              describe :plug_method do
         
     | 
| 
      
 27 
     | 
    
         
            +
                it "defines a singleton method on the proxy object" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  p = SqlcachedClient::ProxyObject.new(Object.new)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  p.plug_method(:sum) do |a, b|
         
     | 
| 
      
 30 
     | 
    
         
            +
                    a + b
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  expect(p.sum(2, 3)).to eq(5)
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -26,12 +26,10 @@ describe SqlcachedClient::Resultset do 
     | 
|
| 
       26 
26 
     | 
    
         
             
                end
         
     | 
| 
       27 
27 
     | 
    
         
             
              end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
29 
     | 
    
         
             
              describe :build_associations do
         
     | 
| 
       31 
30 
     | 
    
         
             
                pending
         
     | 
| 
       32 
31 
     | 
    
         
             
              end
         
     | 
| 
       33 
32 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
33 
     | 
    
         
             
              describe :[] do
         
     | 
| 
       36 
34 
     | 
    
         
             
                it "should be entities[i]" do
         
     | 
| 
       37 
35 
     | 
    
         
             
                  entities = [Object.new] * 3
         
     | 
| 
         @@ -39,4 +37,43 @@ describe SqlcachedClient::Resultset do 
     | 
|
| 
       39 
37 
     | 
    
         
             
                  3.times { |i| expect(r[i]).to eq(entities[i]) }
         
     | 
| 
       40 
38 
     | 
    
         
             
                end
         
     | 
| 
       41 
39 
     | 
    
         
             
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              describe :set_entities_attachments do
         
     | 
| 
      
 42 
     | 
    
         
            +
                let(:resultset) { SqlcachedClient::Resultset.new(nil, nil) }
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                let(:entities) do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  [double(:attach1=)]
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                let(:attachment) { double(:content=, name: 'attach1') }
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                it "sets each attachment to the corresponding entity and saves the content" do
         
     | 
| 
      
 51 
     | 
    
         
            +
                  expect(entities.first).to receive(:attach1=).with(attachment)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  expect(attachment).to receive(:content=).with('content')
         
     | 
| 
      
 53 
     | 
    
         
            +
                  resultset.set_entities_attachments(entities, [attachment], ['content'])
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              describe :store_attachments do
         
     | 
| 
      
 58 
     | 
    
         
            +
                let(:resultset) { SqlcachedClient::Resultset.new(nil, nil) }
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                let(:entities) do
         
     | 
| 
      
 61 
     | 
    
         
            +
                  [
         
     | 
| 
      
 62 
     | 
    
         
            +
                    double(att1: double(to_save_format: 'value a'), attributes: 'attrs a'),
         
     | 
| 
      
 63 
     | 
    
         
            +
                    double(att1: double(to_save_format: 'value b'), attributes: 'attrs b')
         
     | 
| 
      
 64 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                let(:server) { double }
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                it "calls server.store_attachments" do
         
     | 
| 
      
 70 
     | 
    
         
            +
                  expect(server).to receive(:build_store_attachments_request).with(
         
     | 
| 
      
 71 
     | 
    
         
            +
                    ['attrs a', 'attrs b'], ['value a', 'value b']
         
     | 
| 
      
 72 
     | 
    
         
            +
                  ).and_return('attachment request')
         
     | 
| 
      
 73 
     | 
    
         
            +
                  expect(server).to receive(:store_attachments).with('session',
         
     | 
| 
      
 74 
     | 
    
         
            +
                    'attachment request')
         
     | 
| 
      
 75 
     | 
    
         
            +
                  allow(resultset).to receive(:entities).and_return(entities)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  resultset.store_attachments(:att1, server, 'session')
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
       42 
79 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,79 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sqlcached_client/server_responses/query_response'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe SqlcachedClient::ServerResponses::QueryResponse do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:described_class) { SqlcachedClient::ServerResponses::QueryResponse }
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              describe :entities do
         
     | 
| 
      
 7 
     | 
    
         
            +
                context "if body is an array" do
         
     | 
| 
      
 8 
     | 
    
         
            +
                  it "parses each item recoursively" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                    query_response = described_class.new([[1, 2, [3, 4]], 5])
         
     | 
| 
      
 10 
     | 
    
         
            +
                    expect(query_response.entities).to eq(
         
     | 
| 
      
 11 
     | 
    
         
            +
                      [[1, 2, [3, 4]], 5])
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                context "if body is an hash" do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  it "returns the value corresponding to the key 'resultset'" do
         
     | 
| 
      
 17 
     | 
    
         
            +
                    query_response = described_class.new({ 'resultset' => 1 })
         
     | 
| 
      
 18 
     | 
    
         
            +
                    expect(query_response.entities).to eq(1)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  context "if key 'resultset' is not present" do
         
     | 
| 
      
 22 
     | 
    
         
            +
                    it "is nil" do
         
     | 
| 
      
 23 
     | 
    
         
            +
                      query_response = described_class.new({ foo: 'bar' })
         
     | 
| 
      
 24 
     | 
    
         
            +
                      expect(query_response.entities).to be_nil
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  context "if resultset is a string" do
         
     | 
| 
      
 29 
     | 
    
         
            +
                    it "is parsed as json" do
         
     | 
| 
      
 30 
     | 
    
         
            +
                      query_response = described_class.new({
         
     | 
| 
      
 31 
     | 
    
         
            +
                        'resultset' => "{ \"foo\": \"bar\", \"baz\": 1 }"
         
     | 
| 
      
 32 
     | 
    
         
            +
                      })
         
     | 
| 
      
 33 
     | 
    
         
            +
                      expect(query_response.entities).to eq({
         
     | 
| 
      
 34 
     | 
    
         
            +
                        "foo" => "bar", "baz" => 1 })
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              describe :attachments do
         
     | 
| 
      
 41 
     | 
    
         
            +
                context "when body is an Hash" do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  it "is body.attachments" do
         
     | 
| 
      
 43 
     | 
    
         
            +
                    query_response = described_class.new({ 'attachments' => 'foo' })
         
     | 
| 
      
 44 
     | 
    
         
            +
                    expect(query_response.attachments).to eq('foo')
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                context "when body is not an Hash" do
         
     | 
| 
      
 49 
     | 
    
         
            +
                  it "is nil" do
         
     | 
| 
      
 50 
     | 
    
         
            +
                    query_response = described_class.new(['foo', 'bar'])
         
     | 
| 
      
 51 
     | 
    
         
            +
                    expect(query_response.attachments).to be_nil
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              describe :is_array? do
         
     | 
| 
      
 57 
     | 
    
         
            +
                context "when entities is an Array" do
         
     | 
| 
      
 58 
     | 
    
         
            +
                  it "is true" do
         
     | 
| 
      
 59 
     | 
    
         
            +
                    query_response = described_class.new(['foo'])
         
     | 
| 
      
 60 
     | 
    
         
            +
                    expect(query_response.is_array?).to eq(true)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                context "when entities is not an Array" do
         
     | 
| 
      
 65 
     | 
    
         
            +
                  it "is false" do
         
     | 
| 
      
 66 
     | 
    
         
            +
                    query_response = described_class.new({})
         
     | 
| 
      
 67 
     | 
    
         
            +
                    expect(query_response.is_array?).to eq(false)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              describe :flatten! do
         
     | 
| 
      
 73 
     | 
    
         
            +
                it "flattens the entities in place" do
         
     | 
| 
      
 74 
     | 
    
         
            +
                  query_response = described_class.new([[1, [2]], [3]])
         
     | 
| 
      
 75 
     | 
    
         
            +
                  query_response.flatten!
         
     | 
| 
      
 76 
     | 
    
         
            +
                  expect(query_response.entities).to eq([1, 2, 3])
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -12,14 +12,12 @@ describe SqlcachedClient::Server do 
     | 
|
| 
       12 
12 
     | 
    
         
             
                end
         
     | 
| 
       13 
13 
     | 
    
         
             
              end
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
15 
     | 
    
         
             
              describe :build_request do
         
     | 
| 
       17 
16 
     | 
    
         
             
                it "should put the passed value into an hash" do
         
     | 
| 
       18 
17 
     | 
    
         
             
                  expect(server.build_request("foo")).to eq({ batch: "foo" })
         
     | 
| 
       19 
18 
     | 
    
         
             
                end
         
     | 
| 
       20 
19 
     | 
    
         
             
              end
         
     | 
| 
       21 
20 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
21 
     | 
    
         
             
              describe :build_tree_request do
         
     | 
| 
       24 
22 
     | 
    
         
             
                it "should be an Hash with 'tree' and 'root_parameters' keys" do
         
     | 
| 
       25 
23 
     | 
    
         
             
                  expect(server.build_tree_request('tree', 'root')).to eq({
         
     | 
| 
         @@ -28,7 +26,6 @@ describe SqlcachedClient::Server do 
     | 
|
| 
       28 
26 
     | 
    
         
             
                end
         
     | 
| 
       29 
27 
     | 
    
         
             
              end
         
     | 
| 
       30 
28 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
29 
     | 
    
         
             
              describe :build_request_item do
         
     | 
| 
       33 
30 
     | 
    
         
             
                it "should be an hash with id, template, params keys" do
         
     | 
| 
       34 
31 
     | 
    
         
             
                  expect(server.build_request_item("foo", "bar", "baz", "cache")).to eq({
         
     | 
| 
         @@ -40,33 +37,11 @@ describe SqlcachedClient::Server do 
     | 
|
| 
       40 
37 
     | 
    
         
             
                end
         
     | 
| 
       41 
38 
     | 
    
         
             
              end
         
     | 
| 
       42 
39 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                      [[1, 2, [3, 4]], 5])
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
                end
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                context "if body is an hash" do
         
     | 
| 
       53 
     | 
    
         
            -
                  it "should return the value corresponding to the key 'resultset'" do
         
     | 
| 
       54 
     | 
    
         
            -
                    expect(server.parse_response_body({ 'resultset' => 1 })).to eq(1)
         
     | 
| 
       55 
     | 
    
         
            -
                  end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                  context "if key 'resultset' is not present" do
         
     | 
| 
       58 
     | 
    
         
            -
                    it "should be nil" do
         
     | 
| 
       59 
     | 
    
         
            -
                      expect(server.parse_response_body({ foo: 'bar' })).to be_nil
         
     | 
| 
       60 
     | 
    
         
            -
                    end
         
     | 
| 
       61 
     | 
    
         
            -
                  end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                  context "if resultset is a string" do
         
     | 
| 
       64 
     | 
    
         
            -
                    it "should be parsed as json" do
         
     | 
| 
       65 
     | 
    
         
            -
                      expect(server.parse_response_body({
         
     | 
| 
       66 
     | 
    
         
            -
                        'resultset' => "{ \"foo\": \"bar\", \"baz\": 1 }" })).to eq({
         
     | 
| 
       67 
     | 
    
         
            -
                        "foo" => "bar", "baz" => 1 })
         
     | 
| 
       68 
     | 
    
         
            -
                    end
         
     | 
| 
       69 
     | 
    
         
            -
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
              describe :build_store_attachments_request do
         
     | 
| 
      
 41 
     | 
    
         
            +
                it "contains keys resultset and attachments" do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  expect(server.build_store_attachments_request('e', 'a')).to eq({
         
     | 
| 
      
 43 
     | 
    
         
            +
                    resultset: 'e', attachments: 'a'
         
     | 
| 
      
 44 
     | 
    
         
            +
                  })
         
     | 
| 
       70 
45 
     | 
    
         
             
                end
         
     | 
| 
       71 
46 
     | 
    
         
             
              end
         
     | 
| 
       72 
47 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: sqlcached_client
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.1.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Roberto Maestroni
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2015- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2015-08-03 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: activesupport
         
     | 
| 
         @@ -122,13 +122,21 @@ files: 
     | 
|
| 
       122 
122 
     | 
    
         
             
            - Rakefile
         
     | 
| 
       123 
123 
     | 
    
         
             
            - lib/sqlcached_client.rb
         
     | 
| 
       124 
124 
     | 
    
         
             
            - lib/sqlcached_client/arel.rb
         
     | 
| 
      
 125 
     | 
    
         
            +
            - lib/sqlcached_client/attachment.rb
         
     | 
| 
      
 126 
     | 
    
         
            +
            - lib/sqlcached_client/attachments.rb
         
     | 
| 
       125 
127 
     | 
    
         
             
            - lib/sqlcached_client/entity.rb
         
     | 
| 
      
 128 
     | 
    
         
            +
            - lib/sqlcached_client/proxy_object.rb
         
     | 
| 
       126 
129 
     | 
    
         
             
            - lib/sqlcached_client/resultset.rb
         
     | 
| 
       127 
130 
     | 
    
         
             
            - lib/sqlcached_client/server.rb
         
     | 
| 
      
 131 
     | 
    
         
            +
            - lib/sqlcached_client/server_responses/query_response.rb
         
     | 
| 
       128 
132 
     | 
    
         
             
            - lib/sqlcached_client/tree_visitor.rb
         
     | 
| 
       129 
133 
     | 
    
         
             
            - lib/sqlcached_client/version.rb
         
     | 
| 
      
 134 
     | 
    
         
            +
            - spec/sqlcached_client/attachment_spec.rb
         
     | 
| 
      
 135 
     | 
    
         
            +
            - spec/sqlcached_client/attachments_spec.rb
         
     | 
| 
       130 
136 
     | 
    
         
             
            - spec/sqlcached_client/entity_spec.rb
         
     | 
| 
      
 137 
     | 
    
         
            +
            - spec/sqlcached_client/proxy_object_spec.rb
         
     | 
| 
       131 
138 
     | 
    
         
             
            - spec/sqlcached_client/resultset_spec.rb
         
     | 
| 
      
 139 
     | 
    
         
            +
            - spec/sqlcached_client/server_responses/query_response_spec.rb
         
     | 
| 
       132 
140 
     | 
    
         
             
            - spec/sqlcached_client/server_spec.rb
         
     | 
| 
       133 
141 
     | 
    
         
             
            - spec/sqlcached_client/tree_visitor_spec.rb
         
     | 
| 
       134 
142 
     | 
    
         
             
            - sqlcached_client.gemspec
         
     | 
| 
         @@ -157,7 +165,11 @@ signing_key: 
     | 
|
| 
       157 
165 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       158 
166 
     | 
    
         
             
            summary: A Ruby client for sqlcached
         
     | 
| 
       159 
167 
     | 
    
         
             
            test_files:
         
     | 
| 
      
 168 
     | 
    
         
            +
            - spec/sqlcached_client/attachment_spec.rb
         
     | 
| 
      
 169 
     | 
    
         
            +
            - spec/sqlcached_client/attachments_spec.rb
         
     | 
| 
       160 
170 
     | 
    
         
             
            - spec/sqlcached_client/entity_spec.rb
         
     | 
| 
      
 171 
     | 
    
         
            +
            - spec/sqlcached_client/proxy_object_spec.rb
         
     | 
| 
       161 
172 
     | 
    
         
             
            - spec/sqlcached_client/resultset_spec.rb
         
     | 
| 
      
 173 
     | 
    
         
            +
            - spec/sqlcached_client/server_responses/query_response_spec.rb
         
     | 
| 
       162 
174 
     | 
    
         
             
            - spec/sqlcached_client/server_spec.rb
         
     | 
| 
       163 
175 
     | 
    
         
             
            - spec/sqlcached_client/tree_visitor_spec.rb
         
     |