<commit_before># coding: UTF-8
# Proxies management of a table in the users database
require 'forwardable'

require_relative './table/column_typecaster'
require_relative './table/privacy_manager'
require_relative './table/relator'
require_relative './visualization/member'
require_relative '../../services/importer/lib/importer/query_batcher'


class Table < Sequel::Model(:user_tables)
  extend Forwardable

  PRIVACY_PRIVATE = 0
  PRIVACY_PUBLIC = 1
  PRIVACY_LINK = 2

  PRIVACY_PRIVATE_TEXT = 'private'
  PRIVACY_PUBLIC_TEXT = 'public'
  PRIVACY_LINK_TEXT = 'link'

  PRIVACY_VALUES_TO_TEXTS = {
      PRIVACY_PRIVATE => PRIVACY_PRIVATE_TEXT,
      PRIVACY_PUBLIC => PRIVACY_PUBLIC_TEXT,
      PRIVACY_LINK => PRIVACY_LINK_TEXT
  }

  CARTODB_COLUMNS = %W{ cartodb_id created_at updated_at the_geom }
  THE_GEOM_WEBMERCATOR = :the_geom_webmercator
  THE_GEOM = :the_geom
  RESERVED_COLUMN_NAMES = %W{ oid tableoid xmin cmin xmax cmax ctid ogc_fid }
  PUBLIC_ATTRIBUTES = {
      :id                           => :id,
      :name                         => :name,
      :privacy                      => :privacy_text,
      :schema                       => :schema,
      :updated_at                   => :updated_at,
      :rows_counted                 => :rows_estimated,
      :table_size                   => :table_size,
      :map_id                       => :map_id,
      :description                  => :description,
      :geometry_types               => :geometry_types,
      :table_visualization          => :table_visualization,
      :dependent_visualizations     => :serialize_dependent_visualizations,
      :non_dependent_visualizations => :serialize_non_dependent_visualizations,
      :synchronization              => :serialize_synchronization
  }

  DEFAULT_THE_GEOM_TYPE = 'geometry'

  # Associations
  many_to_one  :map
  many_to_many :layers, join_table: :layers_user_tables,
                        left_key:   :user_table_id,
                        right_key:  :layer_id,
                        reciprocal: :user_tables
  one_to_one   :automatic_geocoding
  one_to_many  :geocodings

  plugin :association_dependencies, map:                  :destroy,
                                    layers:               :nullify,
                                    automatic_geocoding:  :destroy
  plugin :dirty

  def_delegators :relator, *CartoDB::Table::Relator::INTERFACE

  def public_values(options = {}, viewer_user=nil)
    selected_attrs = if options[:except].present?
      PUBLIC_ATTRIBUTES.select { |k, v| !options[:except].include?(k.to_sym) }
    else
      PUBLIC_ATTRIBUTES
    end

    attrs = Hash[selected_attrs.map{ |k, v| [k, (self.send(v) rescue self[v].to_s)] }]
    if !viewer_user.nil? && !owner.nil? && owner.id != viewer_user.id
      attrs[:name] = "\"#{owner.database_schema}\".#{attrs[:name]}"
    end
    attrs
  end

  def default_privacy_values
    self.owner.try(:private_tables_enabled) ? PRIVACY_PRIVATE : PRIVACY_PUBLIC
  end #default_privacy_values

  def geometry_types
    owner.in_database[ %Q{
      SELECT DISTINCT ST_GeometryType(the_geom) FROM (
        SELECT the_geom
        FROM "#{self.name}"
        WHERE (the_geom is not null) LIMIT 10
      ) as foo
    }].all.map {|r| r[:st_geometrytype] }
  end

  def_dataset_method(:search) do |query|
    conditions = <<-EOS
      to_tsvector('english', coalesce(name, '') || ' ' || coalesce(description, '')) @@ plainto_tsquery('english', ?) OR name ILIKE ?<commit_msg>fixed table public values<commit_after># coding: UTF-8
# Proxies management of a table in the users database
require 'forwardable'

require_relative './table/column_typecaster'
require_relative './table/privacy_manager'
require_relative './table/relator'
require_relative './visualization/member'
require_relative '../../services/importer/lib/importer/query_batcher'


class Table < Sequel::Model(:user_tables)
  extend Forwardable

  PRIVACY_PRIVATE = 0
  PRIVACY_PUBLIC = 1
  PRIVACY_LINK = 2

  PRIVACY_PRIVATE_TEXT = 'private'
  PRIVACY_PUBLIC_TEXT = 'public'
  PRIVACY_LINK_TEXT = 'link'

  PRIVACY_VALUES_TO_TEXTS = {
      PRIVACY_PRIVATE => PRIVACY_PRIVATE_TEXT,
      PRIVACY_PUBLIC => PRIVACY_PUBLIC_TEXT,
      PRIVACY_LINK => PRIVACY_LINK_TEXT
  }

  CARTODB_COLUMNS = %W{ cartodb_id created_at updated_at the_geom }
  THE_GEOM_WEBMERCATOR = :the_geom_webmercator
  THE_GEOM = :the_geom
  RESERVED_COLUMN_NAMES = %W{ oid tableoid xmin cmin xmax cmax ctid ogc_fid }
  PUBLIC_ATTRIBUTES = {
      :id                           => :id,
      :name                         => :name,
      :privacy                      => :privacy_text,
      :schema                       => :schema,
      :updated_at                   => :updated_at,
      :rows_counted                 => :rows_estimated,
      :table_size                   => :table_size,
      :map_id                       => :map_id,
      :description                  => :description,
      :geometry_types               => :geometry_types,
      :table_visualization          => :table_visualization,
      :dependent_visualizations     => :serialize_dependent_visualizations,
      :non_dependent_visualizations => :serialize_non_dependent_visualizations,
      :synchronization              => :serialize_synchronization
  }

  DEFAULT_THE_GEOM_TYPE = 'geometry'

  # Associations
  many_to_one  :map
  many_to_many :layers, join_table: :layers_user_tables,
                        left_key:   :user_table_id,
                        right_key:  :layer_id,
                        reciprocal: :user_tables
  one_to_one   :automatic_geocoding
  one_to_many  :geocodings

  plugin :association_dependencies, map:                  :destroy,
                                    layers:               :nullify,
                                    automatic_geocoding:  :destroy
  plugin :dirty

  def_delegators :relator, *CartoDB::Table::Relator::INTERFACE

  def public_values(options = {}, viewer_user=nil)
    selected_attrs = if options[:except].present?
      PUBLIC_ATTRIBUTES.select { |k, v| !options[:except].include?(k.to_sym) }
    else
      PUBLIC_ATTRIBUTES
    end

    attrs = Hash[selected_attrs.map{ |k, v| [k, (self.send(v) rescue self[v].to_s)] }]
    if !viewer_user.nil? && !owner.nil? && owner.id != viewer_user.id
      attrs[:name] = "\"#{owner.database_schema}\".#{attrs[:name]}"
    end
    attrs[:table_visualization] = CartoDB::Visualization::Presenter.new(self.table_visualization, { real_privacy: true, user: viewer_user }).to_poro
    attrs
  end

  def default_privacy_values
    self.owner.try(:private_tables_enabled) ? PRIVACY_PRIVATE : PRIVACY_PUBLIC
  end #default_privacy_values

  def geometry_types
    owner.in_database[ %Q{
      SELECT DISTINCT ST_GeometryType(the_geom) FROM (
        SELECT the_geom
        FROM "#{self.name}"
        WHERE (the_geom is not null) LIMIT 10
      ) as foo
    }].all.map {|r| r[:st_geometrytype] }
  end

  def_dataset_method(:search) do |query|
    conditions = <<-EOS
      to_tsvector('english', coalesce(name, '') || ' ' || coalesce(description, '')) @@ plainto_tsquery('english', ?) OR name ILIKE ?
{'fraction_non_alphanumeric': 0.10102283872775676, 'fraction_numerical': 0.0016813787305590584, 'mean_word_length': 2.519723865877712, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5588027', 'n_tokens_mistral': 2414, 'n_tokens_neox': 2302, 'n_words': 418}