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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/CHANGELOG.md +46 -0
- data/README.md +269 -16
- data/docs/README.md +77 -0
- data/docs/configuration.md +340 -0
- data/docs/context.md +292 -0
- data/docs/errors.md +498 -0
- data/docs/integration_testing.md +454 -0
- data/docs/migrator.md +291 -0
- data/docs/rails_integration.md +468 -0
- data/docs/schema_switcher.md +182 -0
- data/docs/tenant_resolver.md +394 -0
- data/docs/testing.md +358 -0
- data/examples/context_management.rb +198 -0
- data/examples/migration_workflow.rb +50 -0
- data/examples/rails_integration/controller_examples.rb +368 -0
- data/examples/schema_operations.rb +124 -0
- data/lib/pg_multitenant_schemas/configuration.rb +4 -4
- data/lib/pg_multitenant_schemas/migration_display_reporter.rb +30 -0
- data/lib/pg_multitenant_schemas/migration_executor.rb +81 -0
- data/lib/pg_multitenant_schemas/migration_schema_operations.rb +54 -0
- data/lib/pg_multitenant_schemas/migration_status_reporter.rb +65 -0
- data/lib/pg_multitenant_schemas/migrator.rb +89 -0
- data/lib/pg_multitenant_schemas/schema_switcher.rb +40 -66
- data/lib/pg_multitenant_schemas/tasks/advanced_tasks.rake +21 -0
- data/lib/pg_multitenant_schemas/tasks/basic_tasks.rake +20 -0
- data/lib/pg_multitenant_schemas/tasks/pg_multitenant_schemas.rake +53 -143
- data/lib/pg_multitenant_schemas/tasks/tenant_tasks.rake +65 -0
- data/lib/pg_multitenant_schemas/tenant_task_helpers.rb +102 -0
- data/lib/pg_multitenant_schemas/version.rb +1 -1
- data/lib/pg_multitenant_schemas.rb +10 -5
- data/pg_multitenant_schemas.gemspec +10 -9
- data/rails_integration/app/controllers/application_controller.rb +6 -0
- data/rails_integration/app/models/tenant.rb +6 -0
- 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,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 (
|
|
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
|
-
#
|
|
21
|
-
#
|
|
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
|
|
14
|
-
"Perfect for SaaS applications requiring
|
|
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.
|
|
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
|
|
37
|
-
spec.add_dependency "activerecord", ">=
|
|
38
|
-
spec.add_dependency "activesupport", ">=
|
|
39
|
-
spec.add_dependency "pg", "~> 1.
|
|
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
|
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.
|
|
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:
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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.
|
|
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.
|
|
67
|
-
description: A Ruby gem that provides PostgreSQL schema-based multitenancy
|
|
68
|
-
tenant resolution
|
|
69
|
-
|
|
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.
|
|
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.
|
|
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: []
|