pg_multitenant_schemas 0.1.3 → 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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -0
  3. data/CHANGELOG.md +46 -0
  4. data/README.md +269 -16
  5. data/docs/README.md +77 -0
  6. data/docs/configuration.md +340 -0
  7. data/docs/context.md +292 -0
  8. data/docs/errors.md +498 -0
  9. data/docs/integration_testing.md +454 -0
  10. data/docs/migrator.md +291 -0
  11. data/docs/rails_integration.md +468 -0
  12. data/docs/schema_switcher.md +182 -0
  13. data/docs/tenant_resolver.md +394 -0
  14. data/docs/testing.md +358 -0
  15. data/examples/context_management.rb +198 -0
  16. data/examples/migration_workflow.rb +50 -0
  17. data/examples/rails_integration/controller_examples.rb +368 -0
  18. data/examples/schema_operations.rb +124 -0
  19. data/lib/pg_multitenant_schemas/configuration.rb +4 -4
  20. data/lib/pg_multitenant_schemas/migration_display_reporter.rb +30 -0
  21. data/lib/pg_multitenant_schemas/migration_executor.rb +81 -0
  22. data/lib/pg_multitenant_schemas/migration_schema_operations.rb +54 -0
  23. data/lib/pg_multitenant_schemas/migration_status_reporter.rb +65 -0
  24. data/lib/pg_multitenant_schemas/migrator.rb +89 -0
  25. data/lib/pg_multitenant_schemas/schema_switcher.rb +40 -66
  26. data/lib/pg_multitenant_schemas/tasks/advanced_tasks.rake +21 -0
  27. data/lib/pg_multitenant_schemas/tasks/basic_tasks.rake +20 -0
  28. data/lib/pg_multitenant_schemas/tasks/pg_multitenant_schemas.rake +53 -143
  29. data/lib/pg_multitenant_schemas/tasks/tenant_tasks.rake +65 -0
  30. data/lib/pg_multitenant_schemas/tenant_task_helpers.rb +102 -0
  31. data/lib/pg_multitenant_schemas/version.rb +1 -1
  32. data/lib/pg_multitenant_schemas.rb +10 -5
  33. data/pg_multitenant_schemas.gemspec +10 -9
  34. data/rails_integration/app/controllers/application_controller.rb +6 -0
  35. data/rails_integration/app/models/tenant.rb +6 -0
  36. metadata +39 -17
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Tenant task helper methods
4
+ module TenantTaskHelpers
5
+ class << self
6
+ def list_tenant_schemas
7
+ puts "šŸ“‹ Available tenant schemas:"
8
+
9
+ schemas = PgMultitenantSchemas::Migrator.send(:tenant_schemas)
10
+
11
+ if schemas.any?
12
+ schemas.each { |schema| puts " - #{schema}" }
13
+ puts "\nšŸ“Š Total: #{schemas.count} tenant schemas"
14
+ else
15
+ puts " No tenant schemas found"
16
+ end
17
+ end
18
+
19
+ def migrate_specific_tenant(schema_name)
20
+ if schema_name.blank?
21
+ puts "Usage: rails tenants:migrate_tenant[schema_name]"
22
+ puts "Example: rails tenants:migrate_tenant[acme_corp]"
23
+ exit 1
24
+ end
25
+
26
+ PgMultitenantSchemas::Migrator.migrate_tenant(schema_name)
27
+ end
28
+
29
+ def create_tenant_with_schema(schema_name)
30
+ if schema_name.blank?
31
+ puts "Usage: rails tenants:create[schema_name]"
32
+ puts "Example: rails tenants:create[acme_corp]"
33
+ exit 1
34
+ end
35
+
36
+ PgMultitenantSchemas::Migrator.setup_tenant(schema_name)
37
+ end
38
+
39
+ def create_tenant_with_attributes(attributes_json)
40
+ if attributes_json.blank?
41
+ puts "Usage: rails tenants:new['{\"subdomain\":\"acme\",\"name\":\"ACME Corp\"}']"
42
+ exit 1
43
+ end
44
+
45
+ begin
46
+ attributes = JSON.parse(attributes_json)
47
+ tenant = PgMultitenantSchemas::Migrator.create_tenant_with_schema(attributes)
48
+ puts "šŸŽ‰ Created tenant: #{tenant.subdomain}"
49
+ rescue JSON::ParserError
50
+ puts "āŒ Invalid JSON format"
51
+ exit 1
52
+ rescue StandardError => e
53
+ puts "āŒ Error creating tenant: #{e.message}"
54
+ exit 1
55
+ end
56
+ end
57
+
58
+ def drop_tenant_schema(schema_name)
59
+ if schema_name.blank?
60
+ puts "Usage: rails tenants:drop[schema_name]"
61
+ exit 1
62
+ end
63
+
64
+ if schema_name == "public"
65
+ puts "āŒ Cannot drop public schema"
66
+ exit 1
67
+ end
68
+
69
+ confirm_schema_drop(schema_name)
70
+ end
71
+
72
+ def rollback_tenant_migrations(schema_name, steps)
73
+ if schema_name.blank?
74
+ puts "Usage: rails tenants:rollback[schema_name,steps]"
75
+ puts "Example: rails tenants:rollback[acme_corp,2]"
76
+ exit 1
77
+ end
78
+
79
+ PgMultitenantSchemas::Migrator.rollback_tenant(schema_name, steps: steps)
80
+ end
81
+
82
+ private
83
+
84
+ def confirm_schema_drop(schema_name)
85
+ print "āš ļø This will permanently delete all data in schema '#{schema_name}'. Continue? (y/N): "
86
+ response = $stdin.gets.chomp.downcase
87
+
88
+ unless %w[y yes].include?(response)
89
+ puts "āŒ Operation cancelled"
90
+ exit 0
91
+ end
92
+
93
+ begin
94
+ PgMultitenantSchemas::SchemaSwitcher.drop_schema(schema_name)
95
+ puts "āœ… Dropped schema: #{schema_name}"
96
+ rescue StandardError => e
97
+ puts "āŒ Error dropping schema #{schema_name}: #{e.message}"
98
+ exit 1
99
+ end
100
+ end
101
+ end
102
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgMultitenantSchemas
4
- VERSION = "0.1.3"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -1,24 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # frozen_string_li# PgMultitenantSchemas provides modern PostgreSQL schema-based multitenancy functionality.
4
+ # Built for Rails 8+ and Ruby 3.4+, it allows switching between different PostgreSQL schemas
5
+ # to achieve secure tenant isolation while maintaining high performance and developer experience.al: true
6
+
3
7
  require "active_support/core_ext/module/delegation"
4
8
  require "active_support/core_ext/object/blank"
5
9
  require_relative "pg_multitenant_schemas/version"
6
10
  require_relative "pg_multitenant_schemas/errors"
7
11
  require_relative "pg_multitenant_schemas/configuration"
8
- require_relative "pg_multitenant_schemas/schema_switcher"
9
12
  require_relative "pg_multitenant_schemas/context"
13
+ require_relative "pg_multitenant_schemas/schema_switcher"
10
14
  require_relative "pg_multitenant_schemas/tenant_resolver"
15
+ require_relative "pg_multitenant_schemas/migrator"
11
16
 
12
- # Rails integration (only load if Rails is available)
17
+ # Rails integration (Rails 8+ required)
13
18
  if defined?(Rails)
14
19
  require_relative "pg_multitenant_schemas/rails/controller_concern"
15
20
  require_relative "pg_multitenant_schemas/rails/model_concern"
16
21
  require_relative "pg_multitenant_schemas/rails/railtie"
17
22
  end
18
23
 
19
- # PgMultitenantSchemas provides PostgreSQL schema-based multitenancy functionality.
20
- # It allows switching between different PostgreSQL schemas to achieve tenant isolation
21
- # while sharing the same database connection. Includes Rails integration support.
24
+ # PgMultitenantSchemas provides modern PostgreSQL schema-based multitenancy functionality.
25
+ # Built for Rails 8+ and Ruby 3.3+, it allows switching between different PostgreSQL schemas
26
+ # to achieve secure tenant isolation while maintaining high performance and developer experience.
22
27
  module PgMultitenantSchemas
23
28
  class << self
24
29
  # Delegate common methods to Context for convenience
@@ -8,13 +8,14 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Ruben Paz"]
9
9
  spec.email = ["rubenpazchuspe@outlook.com"]
10
10
 
11
- spec.summary = "PostgreSQL schema-based multitenancy for Rails applications"
12
- spec.description = "A Ruby gem that provides PostgreSQL schema-based multitenancy with automatic tenant " \
13
- "resolution, schema switching, Rails 8 compatibility, and comprehensive Rails integration. " \
14
- "Perfect for SaaS applications requiring secure tenant isolation."
11
+ spec.summary = "Modern PostgreSQL schema-based multitenancy for Rails 8+ applications"
12
+ spec.description = "A modern Ruby gem that provides PostgreSQL schema-based multitenancy with automatic tenant " \
13
+ "resolution and schema switching. Built for Rails 8+ and Ruby 3.3+, focusing on security, " \
14
+ "performance, and developer experience. Perfect for modern SaaS applications requiring " \
15
+ "secure tenant isolation."
15
16
  spec.homepage = "https://github.com/rubenpazch/pg_multitenant_schemas"
16
17
  spec.license = "MIT"
17
- spec.required_ruby_version = ">= 3.1.0"
18
+ spec.required_ruby_version = ">= 3.0.0"
18
19
 
19
20
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
20
21
  spec.metadata["homepage_uri"] = spec.homepage
@@ -33,8 +34,8 @@ Gem::Specification.new do |spec|
33
34
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
34
35
  spec.require_paths = ["lib"]
35
36
 
36
- # Runtime dependencies - Rails 8 compatible
37
- spec.add_dependency "activerecord", ">= 7.0", "< 9.0"
38
- spec.add_dependency "activesupport", ">= 7.0", "< 9.0"
39
- spec.add_dependency "pg", "~> 1.0"
37
+ # Runtime dependencies - Modern Rails only
38
+ spec.add_dependency "activerecord", ">= 8.0", "< 9.0"
39
+ spec.add_dependency "activesupport", ">= 8.0", "< 9.0"
40
+ spec.add_dependency "pg", "~> 1.5"
40
41
  end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Example application controller for Rails integration testing
4
+ class ApplicationController < ActionController::Base
5
+ # This is a placeholder controller for testing Rails integration
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Example tenant model for Rails integration testing
4
+ class Tenant < ApplicationRecord
5
+ validates :subdomain, presence: true, uniqueness: true
6
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_multitenant_schemas
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruben Paz
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-09-06 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activerecord
@@ -16,7 +15,7 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '7.0'
18
+ version: '8.0'
20
19
  - - "<"
21
20
  - !ruby/object:Gem::Version
22
21
  version: '9.0'
@@ -26,7 +25,7 @@ dependencies:
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- version: '7.0'
28
+ version: '8.0'
30
29
  - - "<"
31
30
  - !ruby/object:Gem::Version
32
31
  version: '9.0'
@@ -36,7 +35,7 @@ dependencies:
36
35
  requirements:
37
36
  - - ">="
38
37
  - !ruby/object:Gem::Version
39
- version: '7.0'
38
+ version: '8.0'
40
39
  - - "<"
41
40
  - !ruby/object:Gem::Version
42
41
  version: '9.0'
@@ -46,7 +45,7 @@ dependencies:
46
45
  requirements:
47
46
  - - ">="
48
47
  - !ruby/object:Gem::Version
49
- version: '7.0'
48
+ version: '8.0'
50
49
  - - "<"
51
50
  - !ruby/object:Gem::Version
52
51
  version: '9.0'
@@ -56,17 +55,18 @@ dependencies:
56
55
  requirements:
57
56
  - - "~>"
58
57
  - !ruby/object:Gem::Version
59
- version: '1.0'
58
+ version: '1.5'
60
59
  type: :runtime
61
60
  prerelease: false
62
61
  version_requirements: !ruby/object:Gem::Requirement
63
62
  requirements:
64
63
  - - "~>"
65
64
  - !ruby/object:Gem::Version
66
- version: '1.0'
67
- description: A Ruby gem that provides PostgreSQL schema-based multitenancy with automatic
68
- tenant resolution, schema switching, Rails 8 compatibility, and comprehensive Rails
69
- integration. Perfect for SaaS applications requiring secure tenant isolation.
65
+ version: '1.5'
66
+ description: A modern Ruby gem that provides PostgreSQL schema-based multitenancy
67
+ with automatic tenant resolution and schema switching. Built for Rails 8+ and Ruby
68
+ 3.3+, focusing on security, performance, and developer experience. Perfect for modern
69
+ SaaS applications requiring secure tenant isolation.
70
70
  email:
71
71
  - rubenpazchuspe@outlook.com
72
72
  executables: []
@@ -76,21 +76,45 @@ files:
76
76
  - ".rspec"
77
77
  - ".rubocop.yml"
78
78
  - ".rubocop_simple.yml"
79
+ - ".ruby-version"
79
80
  - CHANGELOG.md
80
81
  - CODE_OF_CONDUCT.md
81
82
  - LICENSE.txt
82
83
  - README.md
83
84
  - Rakefile
85
+ - docs/README.md
86
+ - docs/configuration.md
87
+ - docs/context.md
88
+ - docs/errors.md
89
+ - docs/integration_testing.md
90
+ - docs/migrator.md
91
+ - docs/rails_integration.md
92
+ - docs/schema_switcher.md
93
+ - docs/tenant_resolver.md
94
+ - docs/testing.md
95
+ - examples/context_management.rb
96
+ - examples/migration_workflow.rb
97
+ - examples/rails_integration/controller_examples.rb
98
+ - examples/schema_operations.rb
84
99
  - lib/pg_multitenant_schemas.rb
85
100
  - lib/pg_multitenant_schemas/configuration.rb
86
101
  - lib/pg_multitenant_schemas/context.rb
87
102
  - lib/pg_multitenant_schemas/errors.rb
103
+ - lib/pg_multitenant_schemas/migration_display_reporter.rb
104
+ - lib/pg_multitenant_schemas/migration_executor.rb
105
+ - lib/pg_multitenant_schemas/migration_schema_operations.rb
106
+ - lib/pg_multitenant_schemas/migration_status_reporter.rb
107
+ - lib/pg_multitenant_schemas/migrator.rb
88
108
  - lib/pg_multitenant_schemas/rails/controller_concern.rb
89
109
  - lib/pg_multitenant_schemas/rails/model_concern.rb
90
110
  - lib/pg_multitenant_schemas/rails/railtie.rb
91
111
  - lib/pg_multitenant_schemas/schema_switcher.rb
112
+ - lib/pg_multitenant_schemas/tasks/advanced_tasks.rake
113
+ - lib/pg_multitenant_schemas/tasks/basic_tasks.rake
92
114
  - lib/pg_multitenant_schemas/tasks/pg_multitenant_schemas.rake
115
+ - lib/pg_multitenant_schemas/tasks/tenant_tasks.rake
93
116
  - lib/pg_multitenant_schemas/tenant_resolver.rb
117
+ - lib/pg_multitenant_schemas/tenant_task_helpers.rb
94
118
  - lib/pg_multitenant_schemas/version.rb
95
119
  - pg_multitenant_schemas.gemspec
96
120
  - rails_integration/app/controllers/application_controller.rb
@@ -104,7 +128,6 @@ metadata:
104
128
  homepage_uri: https://github.com/rubenpazch/pg_multitenant_schemas
105
129
  source_code_uri: https://github.com/rubenpazch/pg_multitenant_schemas
106
130
  changelog_uri: https://github.com/rubenpazch/pg_multitenant_schemas/blob/main/CHANGELOG.md
107
- post_install_message:
108
131
  rdoc_options: []
109
132
  require_paths:
110
133
  - lib
@@ -112,15 +135,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
135
  requirements:
113
136
  - - ">="
114
137
  - !ruby/object:Gem::Version
115
- version: 3.1.0
138
+ version: 3.0.0
116
139
  required_rubygems_version: !ruby/object:Gem::Requirement
117
140
  requirements:
118
141
  - - ">="
119
142
  - !ruby/object:Gem::Version
120
143
  version: '0'
121
144
  requirements: []
122
- rubygems_version: 3.3.27
123
- signing_key:
145
+ rubygems_version: 3.6.7
124
146
  specification_version: 4
125
- summary: PostgreSQL schema-based multitenancy for Rails applications
147
+ summary: Modern PostgreSQL schema-based multitenancy for Rails 8+ applications
126
148
  test_files: []