lib/wcc/contentful/store/cdn_adapter.rb in wcc-contentful-0.2.2 vs lib/wcc/contentful/store/cdn_adapter.rb in wcc-contentful-0.3.0.pre.rc
- old
+ new
@@ -9,65 +9,135 @@
def initialize(client)
super()
@client = client
end
- def find(key)
+ def find(key, hint: nil, **options)
+ options = { locale: '*' }.merge!(options || {})
entry =
- begin
- client.entry(key, locale: '*')
- rescue WCC::Contentful::SimpleClient::NotFoundError
- client.asset(key, locale: '*')
+ if hint
+ client.public_send(hint.underscore, key, options)
+ else
+ begin
+ client.entry(key, options)
+ rescue WCC::Contentful::SimpleClient::NotFoundError
+ client.asset(key, options)
+ end
end
entry&.raw
rescue WCC::Contentful::SimpleClient::NotFoundError
nil
end
- def find_by(content_type:, filter: nil)
+ def find_by(content_type:, filter: nil, options: nil)
# default implementation - can be overridden
- q = find_all(content_type: content_type)
+ q = find_all(content_type: content_type, options: { limit: 1 }.merge!(options || {}))
q = q.apply(filter) if filter
q.first
end
- def find_all(content_type:)
- Query.new(@client, content_type: content_type)
+ def find_all(content_type:, options: nil)
+ Query.new(
+ store: self,
+ client: @client,
+ relation: { content_type: content_type },
+ options: options
+ )
end
class Query < Base::Query
- delegate :count, to: :resolve
+ delegate :count, to: :response
def result
- resolve.items
+ return response.items unless @options[:include]
+
+ response.items.map { |e| resolve_includes(e, @options[:include]) }
end
- def initialize(client, relation)
+ 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)
@client = client
@relation = relation
+ @options = options || {}
+ @extra = extra || {}
end
- def eq(field, expected, context = nil)
- locale = context[:locale] if context.present?
- locale ||= 'en-US'
- Query.new(@client,
- @relation.merge("fields.#{field}.#{locale}" => expected))
+ 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,
+ client: @client,
+ relation: @relation.merge(param => expected),
+ options: @options,
+ **@extra
+ )
end
+ def nested_conditions(field, conditions, context)
+ base_param = parameter(field)
+
+ conditions.reduce(self) do |query, (ref, value)|
+ query.apply({ "#{base_param}.#{parameter(ref)}" => value }, context)
+ end
+ end
+
+ Base::Query::OPERATORS.each do |op|
+ define_method(op) do |field, expected, context = nil|
+ apply_operator(op, field, expected, context)
+ end
+ end
+
private
- def resolve
- return @resolve if @resolve
- @resolve ||=
+ def response
+ @response ||=
if @relation[:content_type] == 'Asset'
@client.assets(
- { locale: '*' }.merge!(@relation.reject { |k| k == :content_type })
+ { locale: '*' }.merge!(@relation.reject { |k| k == :content_type }).merge!(@options)
)
else
- @client.entries({ locale: '*' }.merge!(@relation))
+ @client.entries({ locale: '*' }.merge!(@relation).merge!(@options))
end
+ end
+
+ def resolve_link(val, depth)
+ 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)
+ end
+
+ def parameter(field, operator: nil, context: nil, locale: false)
+ if sys?(field)
+ "#{field}#{op_param(operator)}"
+ elsif id?(field)
+ "sys.#{field}#{op_param(operator)}"
+ else
+ "#{field_reference(field)}#{locale(context) if locale}#{op_param(operator)}"
+ end
+ end
+
+ def locale(context)
+ ".#{(context || {}).fetch(:locale, 'en-US')}"
+ end
+
+ def op_param(operator)
+ operator ? "[#{operator}]" : ''
+ end
+
+ def field_reference(field)
+ return field if nested?(field)
+
+ "fields.#{field}"
+ end
+
+ def nested?(field)
+ field.to_s.include?('.')
end
end
end
end