<commit_before>class Layer < Sequel::Model
  plugin :serialization, :json, :options, :infowindow
  
  ALLOWED_KINDS = %W{ carto tiled background gmapsbase }
  PUBLIC_ATTRIBUTES = %W{ options kind infowindow id order }

  ##
  # Sets default order to the maximum order of the sibling layers + 1  
  #
  def set_default_order(parent)
    max_order = parent.layers_dataset.select(:order).map(&:order).compact.max
    order = (max_order == nil ? 0 : max_order + 1)
    self.update(:order => order) if self.order.blank?
  end

  many_to_many :maps,  :after_add => proc { |layer, parent| layer.set_default_order(parent) }
  many_to_many :users, :after_add => proc { |layer, parent| layer.set_default_order(parent) }
  
  plugin :association_dependencies, :maps => :nullify, :users => :nullify

  def public_values
    Hash[PUBLIC_ATTRIBUTES.map{ |a| [a.sub(/_for_api$/, ''), self.send(a)] }]
  end

  def validate
    super

    errors.add(:kind, "not accepted") unless ALLOWED_KINDS.include?(kind)
  end

  def before_save
    super  

    self.updated_at = Time.now
  end

  def after_save
    super

    # Invalidate varnish cache (vizjson) for all the maps including this layer
    maps.each { |map| map.invalidate_varnish_cache }

    # Invalidate related tables cache on varnish (only for carto layers)
    affected_tables.map &:invalidate_varnish_cache if kind == 'carto'
  end

  ##
  # Returns an array of tables used on the layer
  #
  def affected_tables
    if maps.first.present? && options.present? && options[:query].present?
      begin
        query = options[:query]
        tables_per_statement = maps.first.user.in_database.select { 
          cdb_querytables(Sequel.function(:cdb_querystatements, query))
        }.all

        tables_per_statement.map do |s|
          s[:cdb_querytables].split(',').map do |table_name|
            table_name.gsub!(/[\{\}]/, '') 
            Table.select(:id, :name, :user_id)
              .where(user_id: maps.first.user.id, name: table_name).all
          end
        end.flatten.compact.uniq
      rescue Sequel::DatabaseError
        []
      end
    else
      []
    end
  end

  def key
    "rails:layer_styles:#{self.id}"
  end

  def template_path
    if self.infowindow.present? && self.infowindow['template_name'].present?
      Rails.root.join("lib/assets/javascripts/cartodb/#{self.infowindow['template_name']}.jst.mustache")
    else<commit_msg>Fixes an error detecting the tables affected by a given layer<commit_after>class Layer < Sequel::Model
  plugin :serialization, :json, :options, :infowindow
  
  ALLOWED_KINDS = %W{ carto tiled background gmapsbase }
  PUBLIC_ATTRIBUTES = %W{ options kind infowindow id order }

  ##
  # Sets default order to the maximum order of the sibling layers + 1  
  #
  def set_default_order(parent)
    max_order = parent.layers_dataset.select(:order).map(&:order).compact.max
    order = (max_order == nil ? 0 : max_order + 1)
    self.update(:order => order) if self.order.blank?
  end

  many_to_many :maps,  :after_add => proc { |layer, parent| layer.set_default_order(parent) }
  many_to_many :users, :after_add => proc { |layer, parent| layer.set_default_order(parent) }
  
  plugin :association_dependencies, :maps => :nullify, :users => :nullify

  def public_values
    Hash[PUBLIC_ATTRIBUTES.map{ |a| [a.sub(/_for_api$/, ''), self.send(a)] }]
  end

  def validate
    super

    errors.add(:kind, "not accepted") unless ALLOWED_KINDS.include?(kind)
  end

  def before_save
    super  

    self.updated_at = Time.now
  end

  def after_save
    super

    # Invalidate varnish cache (vizjson) for all the maps including this layer
    maps.each { |map| map.invalidate_varnish_cache }

    # Invalidate related tables cache on varnish (only for carto layers)
    affected_tables.map &:invalidate_varnish_cache if kind == 'carto'
  end

  ##
  # Returns an array of tables used on the layer
  #
  def affected_tables
    if maps.first.present? && options.present? && options.symbolize_keys[:query].present?
      begin
        query = options.symbolize_keys[:query]
        tables_per_statement = maps.first.user.in_database.select { 
          cdb_querytables(Sequel.function(:cdb_querystatements, query))
        }.all

        tables_per_statement.map do |s|
          s[:cdb_querytables].split(',').map do |table_name|
            table_name.gsub!(/[\{\}]/, '') 
            Table.select(:id, :name, :user_id)
              .where(user_id: maps.first.user.id, name: table_name).all
          end
        end.flatten.compact.uniq
      rescue Sequel::DatabaseError
        []
      end
    else
      []
    end
  end

  def key
    "rails:layer_styles:#{self.id}"
  end

  def template_path
    if self.infowindow.present? && self.infowindow['template_name'].present?
      Rails.root.join("lib/assets/javascripts/cartodb/#{self.infowindow['template_name']}.jst.mustache")
    else
{'fraction_non_alphanumeric': 0.11637403021641486, 'fraction_numerical': 0.0012249897917517355, 'mean_word_length': 3.12026913372582, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '6569229', 'n_tokens_mistral': 1657, 'n_tokens_neox': 1597, 'n_words': 367}