<commit_before>class Map < Sequel::Model
  many_to_many :layers, :order => :order, :after_add => proc { |map, layer| 
    layer.set_default_order(map)
  }

  many_to_many :data_layers, :clone => :layers, :right_key => :layer_id, :conditions => { :kind => "carto" }
  many_to_many :base_layers, :clone => :layers, :right_key => :layer_id

  one_to_many :tables
  many_to_one :user

  plugin :association_dependencies, :layers => :nullify
  self.raise_on_save_failure = false

  PUBLIC_ATTRIBUTES = %W{ id user_id provider bounding_box_sw bounding_box_ne center zoom view_bounds_sw view_bounds_ne }

  DEFAULT_OPTIONS = {
    zoom:            3,
    bounding_box_sw: [0, 0],
    bounding_box_ne: [0, 0],
    provider:        'leaflet',
    center:          [30, 0]
  }

  DEFAULT_BOUNDS = { minlon: -179, maxlon: 179, minlat: -85.0511, maxlat: 85.0511 }

  attr_accessor :table_id

  def before_save
    super
    self.updated_at = Time.now
  end

  def after_save
    super
    # Keep updated related table map_id (temporal fix)
    if self.table_id.present?
      related_table = Table.filter(user_id: self.user_id, id: self.table_id).first
      related_table.this.update(map_id: self.id) if self.table_id != related_table.map_id
    end

    self.invalidate_varnish_cache
  end

  def public_values
    Hash[PUBLIC_ATTRIBUTES.map{ |a| [a, self.send(a)] }]
  end

  def validate
    super

    errors.add(:user_id, "can't be blank") if user_id.blank?
    #errors.add(:table_id, "can't be blank") if table_id.blank?
    #errors.add(:user_id, "does not exist") if user_id.present? && User[user_id].nil?
    #errors.add(:table_id, "table #{table_id} doesn't belong to user #{user_id}") if user_id.present? && !User[user_id].tables.select(:id).map(&:id).include?(table_id)
  end

  def invalidate_varnish_cache
    t = self.tables_dataset.select(:id, :user_id, :name).first
    CartoDB::Varnish.new.purge("obj.http.X-Cache-Channel ~ #{t.varnish_key}:vizjson")
  end

  def recalculate_bounds!
    begin
      result = get_map_bounds
      self.update(view_bounds_ne: "[#{result[:maxy]}, #{result[:maxx]}]", view_bounds_sw: "[#{result[:miny]}, #{result[:minx]}]")
    rescue Sequel::DatabaseError => ex
      notify_airbrake(ex)
    end
  end

  def get_map_bounds
    begin
      result = user.in_database.fetch("SELECT ST_XMin(ST_Extent(the_geom)) as minx,ST_YMin(ST_Extent(the_geom)) as miny, ST_XMax(ST_Extent(the_geom)) as maxx,ST_YMax(ST_Extent(the_geom)) as maxy from #{self.tables.first.name} as subq").first
    rescue Sequel::DatabaseError
      result = {}
    end
    
    result[:maxx] = result[:maxx].to_f < DEFAULT_BOUNDS[:minlon] ? DEFAULT_BOUNDS[:minlon] : result[:maxx].to_f > DEFAULT_BOUNDS[:maxlon] ? DEFAULT_BOUNDS[:maxlon] : result[:maxx].to_f<commit_msg>fixes saving a map without table<commit_after>class Map < Sequel::Model
  many_to_many :layers, :order => :order, :after_add => proc { |map, layer| 
    layer.set_default_order(map)
  }

  many_to_many :data_layers, :clone => :layers, :right_key => :layer_id, :conditions => { :kind => "carto" }
  many_to_many :base_layers, :clone => :layers, :right_key => :layer_id

  one_to_many :tables
  many_to_one :user

  plugin :association_dependencies, :layers => :nullify
  self.raise_on_save_failure = false

  PUBLIC_ATTRIBUTES = %W{ id user_id provider bounding_box_sw bounding_box_ne center zoom view_bounds_sw view_bounds_ne }

  DEFAULT_OPTIONS = {
    zoom:            3,
    bounding_box_sw: [0, 0],
    bounding_box_ne: [0, 0],
    provider:        'leaflet',
    center:          [30, 0]
  }

  DEFAULT_BOUNDS = { minlon: -179, maxlon: 179, minlat: -85.0511, maxlat: 85.0511 }

  attr_accessor :table_id

  def before_save
    super
    self.updated_at = Time.now
  end

  def after_save
    super
    # Keep updated related table map_id (temporal fix)
    if self.table_id.present?
      related_table = Table.filter(user_id: self.user_id, id: self.table_id).first
      related_table.this.update(map_id: self.id) if self.table_id != related_table.map_id
    end

    self.invalidate_varnish_cache
  end

  def public_values
    Hash[PUBLIC_ATTRIBUTES.map{ |a| [a, self.send(a)] }]
  end

  def validate
    super

    errors.add(:user_id, "can't be blank") if user_id.blank?
    #errors.add(:table_id, "can't be blank") if table_id.blank?
    #errors.add(:user_id, "does not exist") if user_id.present? && User[user_id].nil?
    #errors.add(:table_id, "table #{table_id} doesn't belong to user #{user_id}") if user_id.present? && !User[user_id].tables.select(:id).map(&:id).include?(table_id)
  end

  def invalidate_varnish_cache
    t = self.tables_dataset.select(:id, :user_id, :name).first
    return true if t.blank?
    CartoDB::Varnish.new.purge("obj.http.X-Cache-Channel ~ #{t.varnish_key}:vizjson")

  end

  def recalculate_bounds!
    begin
      result = get_map_bounds
      self.update(view_bounds_ne: "[#{result[:maxy]}, #{result[:maxx]}]", view_bounds_sw: "[#{result[:miny]}, #{result[:minx]}]")
    rescue Sequel::DatabaseError => ex
      notify_airbrake(ex)
    end
  end

  def get_map_bounds
    begin
      result = user.in_database.fetch("SELECT ST_XMin(ST_Extent(the_geom)) as minx,ST_YMin(ST_Extent(the_geom)) as miny, ST_XMax(ST_Extent(the_geom)) as maxx,ST_YMax(ST_Extent(the_geom)) as maxy from #{self.tables.first.name} as subq").first
    rescue Sequel::DatabaseError
      result = {}
    end
    
    result[:maxx] = result[:maxx].to_f < DEFAULT_BOUNDS[:minlon] ? DEFAULT_BOUNDS[:minlon] : result[:maxx].to_f > DEFAULT_BOUNDS[:maxlon] ? DEFAULT_BOUNDS[:maxlon] : result[:maxx].to_f
{'fraction_non_alphanumeric': 0.1340722202359671, 'fraction_numerical': 0.009295673936360386, 'mean_word_length': 3.9689165186500888, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 25, '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': '1827052', 'n_tokens_mistral': 2145, 'n_tokens_neox': 2063, 'n_words': 412}