pg_rls 0.1.10 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +12 -1
- data/lib/generators/pg_rls/active_record/templates/init_model.rb.tt +0 -3
- data/lib/generators/pg_rls/install_generator.rb +0 -13
- data/lib/generators/templates/pg_rls.rb.tt +11 -0
- data/lib/pg_rls/current/context.rb +10 -0
- data/lib/pg_rls/errors/rake_only_error.rb +1 -1
- data/lib/pg_rls/errors/tenant_not_found.rb +1 -2
- data/lib/pg_rls/logger.rb +31 -0
- data/lib/pg_rls/schema/dumper.rb +36 -0
- data/lib/pg_rls/schema/up_statements.rb +0 -1
- data/lib/pg_rls/tenant.rb +68 -17
- data/lib/pg_rls/version.rb +1 -1
- data/lib/pg_rls.rb +41 -26
- metadata +6 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e81a178c9c3c7d4a42c2dff85faa720c8340a2c3373eab5c38edb50e862bdfb9
         | 
| 4 | 
            +
              data.tar.gz: 8a8d78bd15baca991c1f50eb3adc956f5b467a640c6b6b629d8260e19b608ea4
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c461c7b3263d1e936a04a0693509cef55d4a699169a8d4addd7e5818b02ef608cf1cadc39aee287b5b3d6cc11705e3bf10eefeafbc8d62e3db413b0010ebcb36
         | 
| 7 | 
            +
              data.tar.gz: f216cec76a8d3a5703abd0913decc36ef1344d6327331555e6e97168c5b4cf7aeda46254cf04daaadcca159adf56a3747c54c95be8d16b1f32d5de8dc9e5bd31
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                pg_rls (0.1. | 
| 4 | 
            +
                pg_rls (0.1.10)
         | 
| 5 5 |  | 
| 6 6 | 
             
            GEM
         | 
| 7 7 | 
             
              remote: https://rubygems.org/
         | 
| @@ -109,6 +109,7 @@ GEM | |
| 109 109 | 
             
                kramdown-parser-gfm (1.1.0)
         | 
| 110 110 | 
             
                  kramdown (~> 2.0)
         | 
| 111 111 | 
             
                language_server-protocol (3.17.0.3)
         | 
| 112 | 
            +
                logger (1.6.0)
         | 
| 112 113 | 
             
                loofah (2.21.4)
         | 
| 113 114 | 
             
                  crass (~> 1.0.2)
         | 
| 114 115 | 
             
                  nokogiri (>= 1.12.0)
         | 
| @@ -184,6 +185,8 @@ GEM | |
| 184 185 | 
             
                rbs (2.8.4)
         | 
| 185 186 | 
             
                rdoc (6.5.0)
         | 
| 186 187 | 
             
                  psych (>= 4.0.0)
         | 
| 188 | 
            +
                redis-client (0.22.2)
         | 
| 189 | 
            +
                  connection_pool
         | 
| 187 190 | 
             
                regexp_parser (2.8.2)
         | 
| 188 191 | 
             
                reline (0.3.9)
         | 
| 189 192 | 
             
                  io-console (~> 0.5)
         | 
| @@ -236,6 +239,12 @@ GEM | |
| 236 239 | 
             
                  rubocop-factory_bot (~> 2.22)
         | 
| 237 240 | 
             
                ruby-progressbar (1.13.0)
         | 
| 238 241 | 
             
                ruby2_keywords (0.0.5)
         | 
| 242 | 
            +
                sidekiq (7.3.1)
         | 
| 243 | 
            +
                  concurrent-ruby (< 2)
         | 
| 244 | 
            +
                  connection_pool (>= 2.3.0)
         | 
| 245 | 
            +
                  logger
         | 
| 246 | 
            +
                  rack (>= 2.2.4)
         | 
| 247 | 
            +
                  redis-client (>= 0.22.2)
         | 
| 239 248 | 
             
                solargraph (0.49.0)
         | 
| 240 249 | 
             
                  backport (~> 1.2)
         | 
| 241 250 | 
             
                  benchmark
         | 
| @@ -268,6 +277,7 @@ GEM | |
| 268 277 |  | 
| 269 278 | 
             
            PLATFORMS
         | 
| 270 279 | 
             
              arm64-darwin-22
         | 
| 280 | 
            +
              arm64-darwin-23
         | 
| 271 281 | 
             
              x86_64-linux
         | 
| 272 282 |  | 
| 273 283 | 
             
            DEPENDENCIES
         | 
| @@ -280,6 +290,7 @@ DEPENDENCIES | |
| 280 290 | 
             
              rubocop-rails
         | 
| 281 291 | 
             
              rubocop-rake
         | 
| 282 292 | 
             
              rubocop-rspec
         | 
| 293 | 
            +
              sidekiq
         | 
| 283 294 | 
             
              solargraph
         | 
| 284 295 |  | 
| 285 296 | 
             
            RUBY VERSION
         | 
| @@ -2,9 +2,6 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            <% module_namespacing do -%>
         | 
| 4 4 | 
             
            class <%= PgRls.class_name.camelize %> < <%= parent_class_name.classify %>
         | 
| 5 | 
            -
              def self.current
         | 
| 6 | 
            -
                PgRls::Tenant.fetch
         | 
| 7 | 
            -
              end
         | 
| 8 5 | 
             
            <% attributes.select(&:reference?).each do |attribute| -%>
         | 
| 9 6 | 
             
              belongs_to :<%= attribute.name %><%= ", polymorphic: true" if attribute.polymorphic? %>
         | 
| 10 7 | 
             
            <% end -%>
         | 
| @@ -48,7 +48,6 @@ module PgRls | |
| 48 48 | 
             
                  def copy_initializer
         | 
| 49 49 | 
             
                    raise MissingORMError, orm_error_message unless options[:orm]
         | 
| 50 50 |  | 
| 51 | 
            -
                    inject_include_to_application
         | 
| 52 51 | 
             
                    inject_include_to_application_controller
         | 
| 53 52 | 
             
                    template 'pg_rls.rb.tt', 'config/initializers/pg_rls.rb'
         | 
| 54 53 | 
             
                  end
         | 
| @@ -61,14 +60,6 @@ module PgRls | |
| 61 60 | 
             
                    end
         | 
| 62 61 | 
             
                  end
         | 
| 63 62 |  | 
| 64 | 
            -
                  def inject_include_to_application
         | 
| 65 | 
            -
                    return if aplication_already_included?
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                    gsub_file(APPLICATION_PATH, /(#{Regexp.escape(APPLICATION_LINE)})/mio) do |match|
         | 
| 68 | 
            -
                      "#{match}\n  config.active_record.schema_format = :sql\n"
         | 
| 69 | 
            -
                    end
         | 
| 70 | 
            -
                  end
         | 
| 71 | 
            -
             | 
| 72 63 | 
             
                  def inject_include_to_application_controller
         | 
| 73 64 | 
             
                    return if aplication_controller_already_included?
         | 
| 74 65 |  | 
| @@ -81,10 +72,6 @@ module PgRls | |
| 81 72 | 
             
                    File.readlines(APPLICATION_CONTROLLER_PATH).grep(/include PgRls::MultiTenancy/).any?
         | 
| 82 73 | 
             
                  end
         | 
| 83 74 |  | 
| 84 | 
            -
                  def aplication_already_included?
         | 
| 85 | 
            -
                    File.readlines(APPLICATION_PATH).grep(/config.active_record.schema_format = :sql/).any?
         | 
| 86 | 
            -
                  end
         | 
| 87 | 
            -
             | 
| 88 75 | 
             
                  def environment_already_included?
         | 
| 89 76 | 
             
                    File.readlines(ENVIRONMENT_PATH).grep(%r{require_relative 'initializers/pg_rls'}).any?
         | 
| 90 77 | 
             
                  end
         | 
| @@ -9,6 +9,17 @@ PgRls.setup do |config| | |
| 9 9 | 
             
              config.class_name = :<%= PgRls.class_name %>
         | 
| 10 10 | 
             
              config.table_name = :<%= PgRls.table_name %>
         | 
| 11 11 | 
             
              config.search_methods = <%= PgRls.search_methods %>
         | 
| 12 | 
            +
              # If you are using `solid_queue`, `solid_cache`, or `solid_cable` with a sharding configuration,
         | 
| 13 | 
            +
              # we recommend excluding these shards from Row-Level Security (RLS) to avoid the need to reset
         | 
| 14 | 
            +
              # RLS on each shard.
         | 
| 15 | 
            +
              #
         | 
| 16 | 
            +
              # By default, RLS will be enabled for all shards.
         | 
| 17 | 
            +
              # You can specify which shards to exclude from RLS using the `config.excluded_shards` option:
         | 
| 18 | 
            +
              #
         | 
| 19 | 
            +
              #   config.excluded_shards = []
         | 
| 20 | 
            +
              #
         | 
| 21 | 
            +
              # Note: While it's technically possible to leave `solid_cache` and `solid_cable` under RLS,
         | 
| 22 | 
            +
              # it is generally unnecessary and may introduce complexity without added benefit.
         | 
| 12 23 |  | 
| 13 24 | 
             
              ##
         | 
| 14 25 | 
             
              ## Uncomment this lines if you have a custome user per environment
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'logger'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module PgRls
         | 
| 6 | 
            +
              class Logger
         | 
| 7 | 
            +
                def initialize
         | 
| 8 | 
            +
                  @logger = ::Logger.new($stdout) # You can output to a file if needed
         | 
| 9 | 
            +
                  @logger.level = ::Logger::DEBUG
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def log(message, level: :info)
         | 
| 13 | 
            +
                  case level
         | 
| 14 | 
            +
                  when :debug
         | 
| 15 | 
            +
                    @logger.debug(message)
         | 
| 16 | 
            +
                  when :info
         | 
| 17 | 
            +
                    @logger.info(message)
         | 
| 18 | 
            +
                  when :warn
         | 
| 19 | 
            +
                    @logger.warn(message)
         | 
| 20 | 
            +
                  when :error
         | 
| 21 | 
            +
                    @logger.error(message)
         | 
| 22 | 
            +
                  else
         | 
| 23 | 
            +
                    @logger.info(message)
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def deprecation_warning(message)
         | 
| 28 | 
            +
                  log("[DEPRECATION WARNING]: #{message}", level: :warn)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module PgRls
         | 
| 4 | 
            +
              module Schema
         | 
| 5 | 
            +
                module Dumper
         | 
| 6 | 
            +
                  def table(table, stream)
         | 
| 7 | 
            +
                    temp_stream = StringIO.new
         | 
| 8 | 
            +
                    super(table, temp_stream)
         | 
| 9 | 
            +
                    temp_stream_string = temp_stream.string
         | 
| 10 | 
            +
                    if rls_tenant_table?(table)
         | 
| 11 | 
            +
                      temp_stream_string.gsub!('create_table', 'create_rls_tenant_table')
         | 
| 12 | 
            +
                    elsif rls_table?(table)
         | 
| 13 | 
            +
                      temp_stream_string.gsub!('create_table', 'create_rls_table')
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                    stream.print(temp_stream_string)
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  private
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  def rls_table?(table_name)
         | 
| 22 | 
            +
                    # Logic to determine if the table uses RLS
         | 
| 23 | 
            +
                    # You can check if the table has RLS policies or use a naming convention
         | 
| 24 | 
            +
                    @connection.execute(<<-SQL.squish).any?
         | 
| 25 | 
            +
                      SELECT 1 FROM pg_policies WHERE tablename = #{ActiveRecord::Base.connection.quote(table_name)};
         | 
| 26 | 
            +
                    SQL
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  def rls_tenant_table?(table_name)
         | 
| 30 | 
            +
                    # Logic to determine if the table is a tenant table
         | 
| 31 | 
            +
                    # You can check if the table has a specific column or use a naming convention
         | 
| 32 | 
            +
                    PgRls.table_name.to_s == table_name
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
    
        data/lib/pg_rls/tenant.rb
    CHANGED
    
    | @@ -25,7 +25,7 @@ module PgRls | |
| 25 25 |  | 
| 26 26 | 
             
                      yield(tenant).presence if block_given?
         | 
| 27 27 | 
             
                    ensure
         | 
| 28 | 
            -
                      reset_rls! unless PgRls.test_inline_tenant == true
         | 
| 28 | 
            +
                      reset_rls! unless PgRls.test_inline_tenant == true || PgRls::Current::Context.tenant.blank?
         | 
| 29 29 | 
             
                    end
         | 
| 30 30 | 
             
                  end
         | 
| 31 31 |  | 
| @@ -36,47 +36,92 @@ module PgRls | |
| 36 36 | 
             
                  end
         | 
| 37 37 |  | 
| 38 38 | 
             
                  def fetch!
         | 
| 39 | 
            -
                    PgRls.main_model. | 
| 40 | 
            -
                      tenant_id | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 39 | 
            +
                    PgRls::Current::Context.tenant ||= PgRls.main_model.connection_pool.with_connection do |connection|
         | 
| 40 | 
            +
                      tenant_id = get_tenant_id(connection)
         | 
| 41 | 
            +
                      if tenant_id.present?
         | 
| 42 | 
            +
                        PgRls.main_model.find_by!(
         | 
| 43 | 
            +
                          tenant_id:
         | 
| 44 | 
            +
                        )
         | 
| 45 | 
            +
                      end
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  # rubocop:disable Lint/RescueStandardError
         | 
| 50 | 
            +
                  # rubocop:disable Lint/UselessAssignment
         | 
| 51 | 
            +
                  def get_tenant_id(connection)
         | 
| 52 | 
            +
                    connection.execute("SELECT current_setting('rls.tenant_id')").getvalue(0, 0)
         | 
| 53 | 
            +
                  rescue => e
         | 
| 54 | 
            +
                    nil
         | 
| 44 55 | 
             
                  end
         | 
| 56 | 
            +
                  # rubocop:enable Lint/RescueStandardError
         | 
| 57 | 
            +
                  # rubocop:enable Lint/UselessAssignment
         | 
| 45 58 |  | 
| 46 59 | 
             
                  def reset_rls!
         | 
| 47 60 | 
             
                    PgRls.execute_rls_in_shards do |connection_class|
         | 
| 48 | 
            -
                      connection_class. | 
| 49 | 
            -
                         | 
| 61 | 
            +
                      connection_class.connection_pool.with_connection do |connection|
         | 
| 62 | 
            +
                        connection.transaction do
         | 
| 63 | 
            +
                          connection.execute('RESET rls.tenant_id')
         | 
| 64 | 
            +
                        end
         | 
| 50 65 | 
             
                      end
         | 
| 51 66 | 
             
                    end
         | 
| 52 67 |  | 
| 68 | 
            +
                    PgRls::Current::Context.clear_all
         | 
| 53 69 | 
             
                    nil
         | 
| 54 70 | 
             
                  end
         | 
| 55 71 |  | 
| 56 | 
            -
                  def set_rls!( | 
| 72 | 
            +
                  def set_rls!(tenant)
         | 
| 73 | 
            +
                    tenant_id = tenant.tenant_id
         | 
| 57 74 | 
             
                    PgRls.execute_rls_in_shards do |connection_class|
         | 
| 58 | 
            -
                      connection_class. | 
| 59 | 
            -
                         | 
| 60 | 
            -
             | 
| 75 | 
            +
                      connection_class.connection_pool.with_connection do |connection|
         | 
| 76 | 
            +
                        connection.transaction do
         | 
| 77 | 
            +
                          connection.execute(format('SET rls.tenant_id = %s',
         | 
| 78 | 
            +
                                                    connection.quote(tenant_id)))
         | 
| 79 | 
            +
                        end
         | 
| 61 80 | 
             
                      end
         | 
| 62 81 | 
             
                    end
         | 
| 82 | 
            +
                    PgRls::Current::Context.clear_all
         | 
| 83 | 
            +
                    PgRls::Current::Context.tenant = tenant
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  def on_find_each(ids: [], scope: nil, &)
         | 
| 87 | 
            +
                    raise 'Invalid Scope' if scope.present? && PgRls.main_model != scope.klass
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                    result = []
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                    query = build_on_each_query(ids, scope)
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                    query.find_each do |tenant|
         | 
| 94 | 
            +
                      result << { tenant_id: tenant.id, result: with_tenant!(tenant, &) }
         | 
| 95 | 
            +
                    end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                    result
         | 
| 63 98 | 
             
                  end
         | 
| 64 99 |  | 
| 65 100 | 
             
                  private
         | 
| 66 101 |  | 
| 102 | 
            +
                  def build_on_each_query(ids, scope)
         | 
| 103 | 
            +
                    return PgRls.main_model.all if ids.empty? && scope.blank?
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                    return PgRls.main_model.where(id: ids) if scope.blank?
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                    return scope.where(id: ids) if ids.present?
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                    scope
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
             | 
| 67 112 | 
             
                  def switch_tenant!(resource)
         | 
| 68 113 | 
             
                    tenant = find_tenant(resource)
         | 
| 69 114 |  | 
| 70 | 
            -
                    set_rls!(tenant | 
| 115 | 
            +
                    set_rls!(tenant)
         | 
| 71 116 |  | 
| 72 117 | 
             
                    tenant
         | 
| 73 118 | 
             
                  rescue NoMethodError
         | 
| 74 119 | 
             
                    raise PgRls::Errors::TenantNotFound
         | 
| 120 | 
            +
                  ensure
         | 
| 121 | 
            +
                    reset_rls! if tenant.blank?
         | 
| 75 122 | 
             
                  end
         | 
| 76 123 |  | 
| 77 124 | 
             
                  def find_tenant(resource)
         | 
| 78 | 
            -
                    reset_rls!
         | 
| 79 | 
            -
             | 
| 80 125 | 
             
                    tenant = nil
         | 
| 81 126 |  | 
| 82 127 | 
             
                    PgRls.search_methods.each do |method|
         | 
| @@ -85,14 +130,20 @@ module PgRls | |
| 85 130 | 
             
                      tenant = find_tenant_by_method(resource, method)
         | 
| 86 131 | 
             
                    end
         | 
| 87 132 |  | 
| 133 | 
            +
                    reset_rls! if reset_rls?(tenant)
         | 
| 88 134 | 
             
                    raise PgRls::Errors::TenantNotFound if tenant.blank?
         | 
| 89 135 |  | 
| 90 136 | 
             
                    tenant
         | 
| 91 137 | 
             
                  end
         | 
| 92 138 |  | 
| 139 | 
            +
                  def reset_rls?(tenant)
         | 
| 140 | 
            +
                    PgRls::Current::Context.tenant.present? && tenant.present? && PgRls::Current::Context.tenant != tenant
         | 
| 141 | 
            +
                  end
         | 
| 142 | 
            +
             | 
| 93 143 | 
             
                  def find_tenant_by_method(resource, method)
         | 
| 94 | 
            -
                     | 
| 95 | 
            -
             | 
| 144 | 
            +
                    return resource if resource.is_a?(PgRls.main_model)
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                    PgRls.main_model.unscoped.send(:"find_by_#{method}!", resource)
         | 
| 96 147 | 
             
                  rescue ActiveRecord::RecordNotFound
         | 
| 97 148 | 
             
                    nil
         | 
| 98 149 | 
             
                  end
         | 
    
        data/lib/pg_rls/version.rb
    CHANGED
    
    
    
        data/lib/pg_rls.rb
    CHANGED
    
    | @@ -5,25 +5,31 @@ require 'forwardable' | |
| 5 5 | 
             
            require_relative 'pg_rls/version'
         | 
| 6 6 | 
             
            require_relative 'pg_rls/database/prepared'
         | 
| 7 7 | 
             
            require_relative 'pg_rls/schema/statements'
         | 
| 8 | 
            +
            require_relative 'pg_rls/schema/dumper'
         | 
| 8 9 | 
             
            require_relative 'pg_rls/database/configurations'
         | 
| 9 10 | 
             
            require_relative 'pg_rls/database/admin_statements'
         | 
| 10 11 | 
             
            require_relative 'pg_rls/tenant'
         | 
| 11 12 | 
             
            require_relative 'pg_rls/multi_tenancy'
         | 
| 12 13 | 
             
            require_relative 'pg_rls/railtie' if defined?(Rails)
         | 
| 13 14 | 
             
            require_relative 'pg_rls/errors/index'
         | 
| 15 | 
            +
            require_relative 'pg_rls/current/context'
         | 
| 16 | 
            +
            require_relative 'pg_rls/logger'
         | 
| 14 17 |  | 
| 15 18 | 
             
            ActiveRecord::Migrator.prepend PgRls::Admin::ActiveRecord::Migrator
         | 
| 16 19 | 
             
            ActiveRecord::Tasks::DatabaseTasks.prepend PgRls::Admin::ActiveRecord::Tasks::DatabaseTasks
         | 
| 17 20 | 
             
            ActiveRecord::ConnectionAdapters::AbstractAdapter.include PgRls::Schema::Statements
         | 
| 21 | 
            +
            ActiveRecord::SchemaDumper.prepend PgRls::Schema::Dumper
         | 
| 22 | 
            +
             | 
| 18 23 | 
             
            # PostgreSQL Row Level Security
         | 
| 19 24 | 
             
            module PgRls
         | 
| 20 25 | 
             
              class Error < StandardError; end
         | 
| 21 26 | 
             
              class << self
         | 
| 22 27 | 
             
                extend Forwardable
         | 
| 23 28 |  | 
| 24 | 
            -
                WRITER_METHODS = %i[table_name class_name search_methods].freeze
         | 
| 25 | 
            -
                READER_METHODS = %i[connection_class execute table_name class_name search_methods].freeze
         | 
| 26 | 
            -
                DELEGATORS_METHODS = %i[connection_class execute table_name search_methods class_name main_model | 
| 29 | 
            +
                WRITER_METHODS = %i[table_name class_name search_methods logger excluded_shards].freeze
         | 
| 30 | 
            +
                READER_METHODS = %i[connection_class execute table_name class_name search_methods logger excluded_shards].freeze
         | 
| 31 | 
            +
                DELEGATORS_METHODS = %i[connection_class execute table_name search_methods class_name main_model logger
         | 
| 32 | 
            +
                                        excluded_shards].freeze
         | 
| 27 33 |  | 
| 28 34 | 
             
                attr_writer(*WRITER_METHODS)
         | 
| 29 35 | 
             
                attr_reader(*READER_METHODS)
         | 
| @@ -36,7 +42,7 @@ module PgRls | |
| 36 42 | 
             
                  yield self
         | 
| 37 43 |  | 
| 38 44 | 
             
                  Rails.application.config.to_prepare do
         | 
| 39 | 
            -
                    PgRls.main_model.ignored_columns = []
         | 
| 45 | 
            +
                    PgRls.main_model.ignored_columns = [] # rubocop:disable Rails/IgnoredColumnsAssignment
         | 
| 40 46 | 
             
                  end
         | 
| 41 47 | 
             
                end
         | 
| 42 48 |  | 
| @@ -54,7 +60,6 @@ module PgRls | |
| 54 60 | 
             
                def establish_new_connection!(admin: false)
         | 
| 55 61 | 
             
                  self.as_db_admin = admin
         | 
| 56 62 |  | 
| 57 | 
            -
                  db_config = PgRls.main_model.connection_db_config.configuration_hash
         | 
| 58 63 | 
             
                  execute_rls_in_shards do |connection_class, pool|
         | 
| 59 64 | 
             
                    connection_class.connection_pool.disconnect!
         | 
| 60 65 | 
             
                    connection_class.remove_connection
         | 
| @@ -66,20 +71,23 @@ module PgRls | |
| 66 71 | 
             
                  class_name.to_s.camelize.constantize
         | 
| 67 72 | 
             
                end
         | 
| 68 73 |  | 
| 69 | 
            -
                def on_each_tenant(&)
         | 
| 70 | 
            -
                   | 
| 71 | 
            -
                     | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 77 | 
            -
                      result << { tenant:, result: ensure_block_execution(tenant, &) }
         | 
| 78 | 
            -
                    end
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                    PgRls::Tenant.reset_rls!
         | 
| 74 | 
            +
                def on_each_tenant(ids: [], scope: nil, &)
         | 
| 75 | 
            +
                  logger.deprecation_warning(
         | 
| 76 | 
            +
                    'PgRls.on_each_tenant is deprecated and will be removed in future versions. ' \
         | 
| 77 | 
            +
                    'Please use PgRls::Tenant.on_find_each instead.'
         | 
| 78 | 
            +
                  )
         | 
| 79 | 
            +
                  Tenant.on_find_each(ids:, scope:, &)
         | 
| 80 | 
            +
                end
         | 
| 81 81 |  | 
| 82 | 
            -
             | 
| 82 | 
            +
                rails_version = Gem.loaded_specs['rails'].version
         | 
| 83 | 
            +
                if rails_version >= Gem::Version.new('7.2') && rails_version < Gem::Version.new('7.3')
         | 
| 84 | 
            +
                  def pool_connection(pool)
         | 
| 85 | 
            +
                    pool.lease_connection
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
                else
         | 
| 88 | 
            +
                  def pool_connection(pool)
         | 
| 89 | 
            +
                    PgRls.logger.deprecation_warning('PgRls.pool_connection is deprecated and will be removed in future PgRls 0.2.0. Please use pool.lease_connection instead.')
         | 
| 90 | 
            +
                    pool.connection
         | 
| 83 91 | 
             
                  end
         | 
| 84 92 | 
             
                end
         | 
| 85 93 |  | 
| @@ -88,10 +96,13 @@ module PgRls | |
| 88 96 | 
             
                  result = []
         | 
| 89 97 |  | 
| 90 98 | 
             
                  connection_pool_list.each do |pool|
         | 
| 91 | 
            -
                     | 
| 92 | 
            -
             | 
| 99 | 
            +
                    connection = pool_connection(pool)
         | 
| 100 | 
            +
                    next if excluded_shards.include?(connection.connection_class.connection_db_config.name)
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                    connection.transaction do
         | 
| 103 | 
            +
                      Rails.logger.info("Executing in #{connection.connection_class}")
         | 
| 93 104 |  | 
| 94 | 
            -
                      result << yield( | 
| 105 | 
            +
                      result << yield(connection.connection_class, pool)
         | 
| 95 106 | 
             
                    end
         | 
| 96 107 | 
             
                  end
         | 
| 97 108 |  | 
| @@ -141,11 +152,9 @@ module PgRls | |
| 141 152 | 
             
                end
         | 
| 142 153 |  | 
| 143 154 | 
             
                def execute_query_or_block(query = nil, &)
         | 
| 144 | 
            -
                  if block_given?
         | 
| 145 | 
            -
             | 
| 146 | 
            -
                   | 
| 147 | 
            -
                    execute(query)
         | 
| 148 | 
            -
                  end
         | 
| 155 | 
            +
                  return ensure_block_execution(&) if block_given?
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                  execute(query)
         | 
| 149 158 | 
             
                end
         | 
| 150 159 |  | 
| 151 160 | 
             
                def reset_connection_if_needed(current_tenant, reset_rls_connection)
         | 
| @@ -173,4 +182,10 @@ module PgRls | |
| 173 182 |  | 
| 174 183 | 
             
              mattr_accessor :search_methods
         | 
| 175 184 | 
             
              @@search_methods = %i[subdomain id tenant_id]
         | 
| 185 | 
            +
             | 
| 186 | 
            +
              mattr_accessor :logger
         | 
| 187 | 
            +
              @@logger = PgRls::Logger.new
         | 
| 188 | 
            +
             | 
| 189 | 
            +
              mattr_accessor :excluded_shards
         | 
| 190 | 
            +
              @@excluded_shards = []
         | 
| 176 191 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: pg_rls
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Daniel Laloush
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024- | 
| 11 | 
            +
            date: 2024-09-27 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies: []
         | 
| 13 13 | 
             
            description: |2
         | 
| 14 14 | 
             
                  This gem will help you to integrate PostgreSQL RLS to help you develop a great multitenancy application
         | 
| @@ -47,6 +47,7 @@ files: | |
| 47 47 | 
             
            - lib/generators/templates/pg_rls.rb.tt
         | 
| 48 48 | 
             
            - lib/pg_rls.rb
         | 
| 49 49 | 
             
            - lib/pg_rls/Rakefile
         | 
| 50 | 
            +
            - lib/pg_rls/current/context.rb
         | 
| 50 51 | 
             
            - lib/pg_rls/database/admin_statements.rb
         | 
| 51 52 | 
             
            - lib/pg_rls/database/configurations.rb
         | 
| 52 53 | 
             
            - lib/pg_rls/database/prepared.rb
         | 
| @@ -54,6 +55,7 @@ files: | |
| 54 55 | 
             
            - lib/pg_rls/errors/index.rb
         | 
| 55 56 | 
             
            - lib/pg_rls/errors/rake_only_error.rb
         | 
| 56 57 | 
             
            - lib/pg_rls/errors/tenant_not_found.rb
         | 
| 58 | 
            +
            - lib/pg_rls/logger.rb
         | 
| 57 59 | 
             
            - lib/pg_rls/middleware.rb
         | 
| 58 60 | 
             
            - lib/pg_rls/middleware/set_reset_connection.rb
         | 
| 59 61 | 
             
            - lib/pg_rls/middleware/sidekiq.rb
         | 
| @@ -62,6 +64,7 @@ files: | |
| 62 64 | 
             
            - lib/pg_rls/multi_tenancy.rb
         | 
| 63 65 | 
             
            - lib/pg_rls/railtie.rb
         | 
| 64 66 | 
             
            - lib/pg_rls/schema/down_statements.rb
         | 
| 67 | 
            +
            - lib/pg_rls/schema/dumper.rb
         | 
| 65 68 | 
             
            - lib/pg_rls/schema/statements.rb
         | 
| 66 69 | 
             
            - lib/pg_rls/schema/up_statements.rb
         | 
| 67 70 | 
             
            - lib/pg_rls/tenant.rb
         | 
| @@ -86,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 86 89 | 
             
                - !ruby/object:Gem::Version
         | 
| 87 90 | 
             
                  version: '0'
         | 
| 88 91 | 
             
            requirements: []
         | 
| 89 | 
            -
            rubygems_version: 3.5. | 
| 92 | 
            +
            rubygems_version: 3.5.16
         | 
| 90 93 | 
             
            signing_key: 
         | 
| 91 94 | 
             
            specification_version: 4
         | 
| 92 95 | 
             
            summary: Write a short summary, because RubyGems requires one.
         |