lib/wcc/contentful/store/cdn_adapter.rb in wcc-contentful-0.4.0.pre.rc vs lib/wcc/contentful/store/cdn_adapter.rb in wcc-contentful-1.0.0.pre.rc1

- old
+ new

@@ -1,16 +1,33 @@ # frozen_string_literal: true module WCC::Contentful::Store class CDNAdapter - attr_reader :client + include WCC::Contentful::Store::Interface + # Note: CDNAdapter should not instrument store events cause it's not a store. + attr_writer :client, :preview_client + + def client + @preview ? @preview_client : @client + end + + # The CDNAdapter cannot index data coming back from the Sync API. + def index? + false + end + + def index + raise NotImplementedError, 'Cannot put data to the CDN!' + end + # Intentionally not implementing write methods - def initialize(client) + def initialize(client = nil, preview: false) super() @client = client + @preview = preview end def find(key, hint: nil, **options) options = { locale: '*' }.merge!(options || {}) entry = @@ -35,43 +52,65 @@ q.first end def find_all(content_type:, options: nil) Query.new( - store: self, - client: @client, + self, + client: client, relation: { content_type: content_type }, options: options ) end - class Query < Base::Query + class Query + include WCC::Contentful::Store::Query::Interface + include Enumerable + + # by default all enumerable methods delegated to the lazy enumerable + delegate(*(Enumerable.instance_methods - Module.instance_methods), to: :to_enum) + + # response.count gets the number of items delegate :count, to: :response - def result + def to_enum return response.items unless @options[:include] response.items.map { |e| resolve_includes(e, @options[:include]) } end - def initialize(store:, client:, relation:, options: nil, **extra) + def initialize(store, client:, relation:, options: nil, **extra) raise ArgumentError, 'Client cannot be nil' unless client.present? raise ArgumentError, 'content_type must be provided' unless relation[:content_type].present? - super(store) + @store = store @client = client @relation = relation @options = options || {} @extra = extra || {} end + # Called with a filter object by {Base#find_by} in order to apply the filter. + def apply(filter, context = nil) + filter.reduce(self) do |query, (field, value)| + if value.is_a?(Hash) + if op?(k = value.keys.first) + query.apply_operator(k.to_sym, field.to_s, value[k], context) + else + query.nested_conditions(field, value, context) + end + else + query.apply_operator(:eq, field.to_s, value) + end + end + end + def apply_operator(operator, field, expected, context = nil) op = operator == :eq ? nil : operator param = parameter(field, operator: op, context: context, locale: true) self.class.new( - store: @store, + @store, client: @client, relation: @relation.merge(param => expected), options: @options, **@extra ) @@ -83,18 +122,30 @@ conditions.reduce(self) do |query, (ref, value)| query.apply({ "#{base_param}.#{parameter(ref)}" => value }, context) end end - Base::Query::OPERATORS.each do |op| + WCC::Contentful::Store::Query::Interface::OPERATORS.each do |op| define_method(op) do |field, expected, context = nil| apply_operator(op, field, expected, context) end end private + def op?(key) + WCC::Contentful::Store::Query::Interface::OPERATORS.include?(key.to_sym) + end + + def sys?(field) + field.to_s =~ /sys\./ + end + + def id?(field) + field.to_sym == :id + end + def response @response ||= if @relation[:content_type] == 'Asset' @client.assets( { locale: '*' }.merge!(@relation.reject { |k| k == :content_type }).merge!(@options) @@ -102,14 +153,22 @@ else @client.entries({ locale: '*' }.merge!(@relation).merge!(@options)) end end - def resolve_link(val, depth) + def resolve_includes(entry, depth) + return entry unless entry && depth && depth > 0 + + WCC::Contentful::LinkVisitor.new(entry, :Link, :Asset, depth: depth - 1).map! do |val| + resolve_link(val) + end + end + + def resolve_link(val) return val unless val.is_a?(Hash) && val.dig('sys', 'type') == 'Link' return val unless included = response.includes[val.dig('sys', 'id')] - resolve_includes(included, depth - 1) + included end def parameter(field, operator: nil, context: nil, locale: false) if sys?(field) "#{field}#{op_param(operator)}"