<commit_before>class ActiveRecord::Base
  class << self
    public :sanitize_sql
  end
  
  %w(execute select_value select_values select_all).each do |method_name|
    define_method("#{method_name}_sql") do |sql, *params|
      ActiveRecord::Base.connection.__send__(method_name, self.class.sanitize_sql([sql, *params]))
    end

    self.class.__send__(:define_method, "#{method_name}_sql") do |sql, *params|
      ActiveRecord::Base.connection.__send__(method_name, ActiveRecord::Base.sanitize_sql([sql, *params]))
    end
  end
end

class NilClass
  def id
    raise NoMethodError
  end
end

class String
  def to_escaped_for_sql_like
    # NOTE: gsub(/\\/, '\\\\') is a NOP, you need gsub(/\\/, '\\\\\\') if you want to turn \ into \\; or you can duplicate the matched text
    return self.gsub(/\\/, '\0\0').gsub(/%/, '\\%').gsub(/_/, '\\_').gsub(/\*/, '%')
  end

  def to_escaped_js
    return self.gsub(/\\/, '\0\0').gsub(/['"]/) {|m| "\\#{m}"}.gsub(/\r\n|\r|\n/, '\\n')
  end
end

class Hash
  def included(m)
    m.alias_method :to_xml_orig, :to_xml
  end
  
  def to_xml(options = {})
    if false == options.delete(:no_children)
      to_xml_orig(options)
    else
      options[:indent] ||= 2
      options[:no_children] ||= true
      options[:root] ||= "hash"
      dasherize = !options.has_key?(:dasherize) || options[:dasherize]
      root = dasherize ? options[:root].dasherize : options[:root]
      options.reverse_merge!({:builder => Builder::XmlMarkup.new(:indent => options[:indent]), :root => root})
      options[:builder].instruct! unless options.delete(:skip_instruct)
      options[:builder].tag!(root, self)
    end
  end
end
<commit_msg>fixup Hash.to_xml to handle array and hash values; implement Array.to_xml<commit_after>class ActiveRecord::Base
  class << self
    public :sanitize_sql
  end
  
  %w(execute select_value select_values select_all).each do |method_name|
    define_method("#{method_name}_sql") do |sql, *params|
      ActiveRecord::Base.connection.__send__(method_name, self.class.sanitize_sql([sql, *params]))
    end

    self.class.__send__(:define_method, "#{method_name}_sql") do |sql, *params|
      ActiveRecord::Base.connection.__send__(method_name, ActiveRecord::Base.sanitize_sql([sql, *params]))
    end
  end
end

class NilClass
  def id
    raise NoMethodError
  end
end

class String
  def to_escaped_for_sql_like
    # NOTE: gsub(/\\/, '\\\\') is a NOP, you need gsub(/\\/, '\\\\\\') if you want to turn \ into \\; or you can duplicate the matched text
    return self.gsub(/\\/, '\0\0').gsub(/%/, '\\%').gsub(/_/, '\\_').gsub(/\*/, '%')
  end

  def to_escaped_js
    return self.gsub(/\\/, '\0\0').gsub(/['"]/) {|m| "\\#{m}"}.gsub(/\r\n|\r|\n/, '\\n')
  end
end

class Hash
  alias_method :to_xml_orig, :to_xml
  
  def to_xml(options = {})
    options[:indent] ||= 2
    options[:root] ||= "hash"
    dasherize = !options.has_key?(:dasherize) || options[:dasherize]
    root = options.delete(:root).to_s
    root = root.dasherize if dasherize

    # Treat simple values as attributes, and complex values as children.
    # { :a=>1, :b=>[1] }
    attrs = {}
    children = []
    self.each do |key, value|
      if value.respond_to?(:to_xml) or value.is_a?(Array) then
        # If an array child is empty, omit the node entirely.
        next if value.is_a?(Array) and value.empty?
        children << [key, value]
      else
        attrs[key] = value
      end
    end

    options.reverse_merge!({:builder => Builder::XmlMarkup.new(:indent => options[:indent])})
    if not options[:skip_instruct]
      options[:skip_instruct] = true
      options[:builder].instruct!
    end

    if children.empty? then
      options[:builder].tag!(root, attrs)
    else
      options[:builder].tag!(root, attrs) {
        children.each do |key, child|
          child.to_xml(options.merge(:root => key.to_s))
        end
      }
    end
  end
end

class Array
  alias_method :to_xml_orig, :to_xml

  def to_xml(options = {})
    options[:builder] ||= Builder::XmlMarkup.new
    root = options.delete(:root) || "array"
    options[:builder].tag!(root) do
      self.each do |value|
        value.to_xml(options)
      end
    end
  end
end

{'fraction_non_alphanumeric': 0.1670638703527169, 'fraction_numerical': 0.002859866539561487, 'mean_word_length': 3.0629235237173282, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 15}, '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': '1276013', 'n_tokens_mistral': 1456, 'n_tokens_neox': 1453, 'n_words': 328}