module ListGroupModule
class Base
class ListResult
- attr :list, :items, :paginate
+ attr :list, :items, :count, :paginate
- def initialize list, items, paginate, operators, options
+ def initialize list, items, count, paginate, operators
@list = list
@items = items
+ @count = count # total count
@paginate = paginate
@operators = operators
- @options = options
end
def path
- if list_manifest.has_id?
- filter_item_id = @options[:id]
- if list_manifest.pre_id?
- '/' + list_manifest.model.path_name + '/' + filter_item_id.to_s + '/' + list_manifest.action_name
- else
- '/' + list_manifest.model.path_name + '/' + list_manifest.action_name + '/' + filter_item_id.to_s
- end
- else
- '/' + list_manifest.model.path_name + '/' + list_manifest.action_name
- end
- end
-
- def list_manifest
- @list.list_manifest
+ @list.action_manifest.url @list.options
end
end
- attr :item_name, :list_name,
- :model_manifest, :model_list_manifest, :list_manifest, :model,
- :default_page_size, :max_page_size
- def initialize item_name, list_name
- @item_name = item_name
+ attr :list_group_name, :list_name, :options, :item_name,
+ :controller_manifest, :action_manifest, :list_manifest, :model,
+ :count
+ def initialize list_group_name, list_name, operators, options = {}
+ @list_group_name = list_group_name
@list_name = list_name
- self.init
- end
-
- def init
- @list_group_manifest = LocalManifest.manifest.list_groups[@item_name]
+ @operators = operators
+ @options = options
+
+ @list_group_manifest = LocalManifest.manifest.list_groups[@list_group_name]
@list_manifest = @list_group_manifest.lists[@list_name]
@where = @list_manifest.where
@includes = @list_manifest.includes
- @order = @list_manifest.order
- @model_manifest = ::Manifest.manifest.models[@item_name]
- @model_list_manifest = @model_manifest.list
+
+ @controller_name = @list_group_name
+ @action_name = @list_name
+ @controller_manifest = ::Manifest.manifest.controllers[@controller_name]
+ @action_manifest = @controller_manifest.actions[@action_name]
+ @item_name = @action_manifest.item_name
@model = ::Manifest.item_name_to_model @item_name
@table_name = @model.table_name
+ self.init
+ end
+
+ def init
+ self.set_count
+ self.set_offset
+ self.set_limit
end
def model_name
@model.model_name
end
- def model_manifest
- @model.model_manifest
+ def set_offset
+ if prm = @options['offset'] || @options[:offset]
+ @offset = prm.to_i
+ @offset = @count - 1 if @offset >= @count
+ @offset = @count - @offset.abs if @offset < 0
+ @offset = 0 if @offset < 0
+ offset
+ else
+ @offset = (self.fixed_page - 1) * self.fixed_page_size
+ end
+ @offset
+ end
+
+ def limit?
+ self.max_page_size > 0
+ end
+
+ def unlimit?
+ !limit?
end
- def page_number prm = nil
- page = prm.to_i
+ def fixed_page
+ page = self.opt_page.to_i
page = 1 if page < 1
page
end
- def page_size prm
- page_size = prm.to_i
- page_size = self.max_page_size if page_size > self.max_page_size
- page_size = self.default_page_size if page_size < 1
+ def fixed_page_size
+ page_size = self.opt_page_size || self.default_page_size
+ page_size = self.max_page_size if self.limit? and (page_size > self.max_page_size)
page_size
end
+ def set_limit
+ prm = self.opt_page_size || self.opt_count
+ @limit = prm.to_i
+ if self.max_page_size > 0
+ @limit = self.max_page_size if @limit > self.max_page_size
+ else # unlimited api
+ @limit = @count if @limit > @count
+ end
+ @limit = self.default_page_size if @limit < 1
+ @limit
+ end
+
+ def opt_page
+ n = @options['page'] || @options[:page]
+ n ? n.to_i : nil
+ end
+
+ def opt_page_size
+ n = @options['page_size'] || @options[:page_size]
+ n ? n.to_i : nil
+ end
+
+ def opt_count
+ n = @options['count'] || @options[:count]
+ n ? n.to_i : nil
+ end
+
def default_page_size
- @model_list_manifest.default_page_size
+ @action_manifest.default_page_size
end
def max_page_size
- @model_list_manifest.max_page_size
+ @action_manifest.max_page_size
+ end
+
+ def order
+ order = @options['order'] || @options[:order] || @action_manifest.order
+ order = 'updated_at' unless ::Manifest.manifest.models[@item_name].attributes[order]
+ @table_name + '.' + order
+ end
+
+ def direction
+ direction = @options['direction'] || @options[:direction] || @action_manifest.direction
+ if direction < 0
+ 'desc'
+ elsif direction > 0
+ 'asc'
+ else
+ ''
+ end
+ end
+
+ def filter_id
+ @options['id'] || @options[:id]
+ end
+
+ def order_by
+ self.order + ' ' + self.direction
end
def base_where_condition
@includes.includes
end
- def order
- @model.__send__ @order.order
- end
-
- def items operators, options, offset, page_size
- @model.where(self.where_condition).includes(self.include_hash).order(self.order).offset(offset).limit(page_size)
+ def items
+ @model.where(
+ self.where_condition
+ ).includes(
+ self.include_hash
+ ).order(
+ self.order_by
+ ).offset(@offset).limit(@limit)
end
- def count operators, options
- @model.where(self.where_condition).includes(self.include_hash).count
+ def set_count
+ @count = @model.where(
+ self.where_condition
+ ).includes(
+ self.include_hash
+ ).count
end
- def paginate count, page, page_size
+ def paginate count
c = count ? count.to_i : 0
- Kaminari.paginate_array(Array.new(c, nil)).page(page).per(page_size)
+ Kaminari.paginate_array(Array.new(c, nil)).page(self.fixed_page).per(self.fixed_page_size)
end
def boost_manifests
end
end
- def open operators, options
- page = self.page_number(options[:page])
- page_size = self.page_size options[:page_size]
- offset = (page -1) * page_size
- items = self.items operators, options, offset, page_size
- count = self.count operators, options
- pg = self.paginate count, page, page_size
+ def open operators
+ items = self.items
+ pg = if limit?
+ self.paginate @count
+ else
+ nil
+ end
self.boost items
- ListResult.new self, items, pg, operators, options
+ ListResult.new self, items, @count, pg, @operators
end
end