<commit_before>#    OOOR: Open Object On Rails
#    Copyright (C) 2009-2011 Akretion LTDA (<http://www.akretion.com>).
#    Author: <NAME>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

#TODO chainability of where via scopes
#TODO include relations for single read

module Ooor
  # = Similar to Active Record Relation
  class Relation
    
    attr_reader :klass, :loaded
    attr_accessor :context, :count_field, :includes_values, :eager_load_values, :preload_values,
                  :select_values, :group_values, :order_values, :reorder_flag, :joins_values, :where_values, :having_values,
                  :limit_value, :offset_value, :lock_value, :readonly_value, :create_with_value, :from_value
    alias :loaded? :loaded
    
    def build_where(opts, other = [])
      case opts
      when Array
        [opts]
      when Hash
        opts.keys.map {|key|["#{key}", "=", opts[key]]}
      end
    end
    
    def where(opts, *rest)
      relation = clone
      relation.where_values += build_where(opts, rest) unless opts.blank?
      relation
    end

#    def having(*args)
#      relation = clone
#      relation.having_values += build_where(*args) unless args.blank?
#      relation
#    end

    def limit(value)
      relation = clone
      relation.limit_value = value
      relation
    end

    def offset(value)
      relation = clone
      relation.offset_value = value
      relation
    end
    
    def order(*args)
      relation = clone
      relation.order_values += args.flatten unless args.blank?
      relation
    end
    
    def count(column_name = nil, options = {})
      column_name, options = nil, column_name if column_name.is_a?(Hash)
      calculate(:count, column_name, options)
    end
    
    def initialize(klass)
      @klass = klass
      @where_values = []
      @loaded = false
      @context = {}
      @count_field = false
      @limit_value = false
      @offset_value = false
      @order_values = []
    end
    
    def new(*args, &block)
      #TODO inject current domain in *args
      @klass.new(*args, &block)
    end
    
    def reload
      reset
      to_a # force reload
      self
    end

    def initialize_copy(other)
      reset
    end

    def reset
      @first = @last = @to_sql = @order_clause = @scope_for_create = @arel = @loaded = nil
      @should_eager_load = @join_dependency = nil
      @records = []
      self
    end

    # A convenience wrapper for <tt>find(:all, *args)</tt>. You can pass in all the
    # same arguments to this method as you can to <tt>find(:all)</tt>.
    def all(*args)
      #args.any? ? apply_finder_options(args.first).to_a : to_a TODO
      to_a
    end

    def to_a
      return @records if loaded?
      if @order_values.empty?
        search_order = false
      else
        search_order = @order_values.join(", ")
      end
      ids = @klass.rpc_execute('search', @where_values, @offset_value, @limit_value, search_order, @context, @count_field)
      @records = @klass.find(ids)
      @loaded = true
      @records
    end
  
    def eager_loading?
      false
    end
    
    protected

    def method_missing(method, *args, &block)
      if Array.method_defined?(method)
        to_a.send(method, *args, &block)
      else
        @klass.rpc_execute(method.to_s, to_a.map {|record| record.id}, *args)
      end
    end

  end
end<commit_msg>better Ooor::Relation implementation<commit_after>#    OOOR: Open Object On Rails
#    Copyright (C) 2009-2011 Akretion LTDA (<http://www.akretion.com>).
#    Author: <NAME>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

#TODO chainability of where via scopes
#TODO include relations for single read
require 'will_paginate/finders'
require 'will_paginate/finders/base'

module Ooor
  # = Similar to Active Record Relation
  class Relation
    
    attr_reader :klass, :loaded
    attr_accessor :context, :count_field, :includes_values, :eager_load_values, :preload_values,
                  :select_values, :group_values, :order_values, :reorder_flag, :joins_values, :where_values, :having_values,
                  :limit_value, :offset_value, :lock_value, :readonly_value, :create_with_value, :from_value
    alias :loaded? :loaded
    
    def build_where(opts, other = [])
      case opts
      when Array
        [opts]
      when Hash
        opts.keys.map {|key|["#{key}", "=", opts[key]]}
      end
    end
    
    def where(opts, *rest)
      relation = clone
      relation.where_values += build_where(opts, rest) unless opts.blank?
      relation
    end

#    def having(*args)
#      relation = clone
#      relation.having_values += build_where(*args) unless args.blank?
#      relation
#    end

    def limit(value)
      relation = clone
      relation.limit_value = value
      relation
    end

    def offset(value)
      relation = clone
      relation.offset_value = value
      relation
    end
    
    def order(*args)
      relation = clone
      relation.order_values += args.flatten unless args.blank?
      relation
    end
    
    def count(column_name = nil, options = {})
      column_name, options = nil, column_name if column_name.is_a?(Hash)
      calculate(:count, column_name, options)
    end
    
    def initialize(klass)
      @klass = klass
      @where_values = []
      @loaded = false
      @context = {}
      @count_field = false
      @limit_value = false
      @offset_value = false
      @order_values = []
    end
    
    def new(*args, &block)
      #TODO inject current domain in *args
      @klass.new(*args, &block)
    end
    
    def reload
      reset
      to_a # force reload
      self
    end

    def initialize_copy(other)
      reset
    end

    def reset
      @first = @last = @to_sql = @order_clause = @scope_for_create = @arel = @loaded = nil
      @should_eager_load = @join_dependency = nil
      @records = []
      self
    end

    # A convenience wrapper for <tt>find(:all, *args)</tt>. You can pass in all the
    # same arguments to this method as you can to <tt>find(:all)</tt>.
    def all(*args)
      #args.any? ? apply_finder_options(args.first).to_a : to_a TODO
      to_a
    end

    def to_a
      return @records if loaded?
      if @order_values.empty?
        search_order = false
      else
        search_order = @order_values.join(", ")
      end
      ids = @klass.rpc_execute('search', @where_values, @offset_value, @limit_value, search_order, @context, @count_field)
      @records = @klass.find(ids)
      @loaded = true
      @records
    end
  
    def eager_loading?
      false
    end
    
    protected

    def method_missing(method, *args, &block)
      if Array.method_defined?(method)
        to_a.send(method, *args, &block)
      elsif @klass.respond_to?(method)
        @klass.send(method, *args, &block)
      else
        @klass.rpc_execute(method.to_s, to_a.map {|record| record.id}, *args)
      end
    end

  end
end
{'fraction_non_alphanumeric': 0.09339853300733496, 'fraction_numerical': 0.002200488997555012, 'mean_word_length': 2.5066438062580367, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1750606', 'n_tokens_mistral': 2518, 'n_tokens_neox': 2489, 'n_words': 764}