pg_multitenant_schemas 0.1.3 โ†’ 0.2.2

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.actrc +17 -0
  3. data/.env.local.example +21 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +86 -0
  6. data/LOCAL_TESTING_SUMMARY.md +141 -0
  7. data/README.md +269 -16
  8. data/TESTING_LOCALLY.md +208 -0
  9. data/docs/README.md +81 -0
  10. data/docs/configuration.md +340 -0
  11. data/docs/context.md +292 -0
  12. data/docs/errors.md +498 -0
  13. data/docs/github_actions_permissions_fix.md +136 -0
  14. data/docs/github_actions_setup.md +181 -0
  15. data/docs/integration_testing.md +454 -0
  16. data/docs/local_workflow_testing.md +314 -0
  17. data/docs/migrator.md +291 -0
  18. data/docs/rails_integration.md +468 -0
  19. data/docs/schema_switcher.md +182 -0
  20. data/docs/tenant_resolver.md +394 -0
  21. data/docs/testing.md +358 -0
  22. data/examples/context_management.rb +198 -0
  23. data/examples/migration_workflow.rb +50 -0
  24. data/examples/rails_integration/controller_examples.rb +368 -0
  25. data/examples/schema_operations.rb +124 -0
  26. data/lib/pg_multitenant_schemas/configuration.rb +4 -4
  27. data/lib/pg_multitenant_schemas/migration_display_reporter.rb +30 -0
  28. data/lib/pg_multitenant_schemas/migration_executor.rb +81 -0
  29. data/lib/pg_multitenant_schemas/migration_schema_operations.rb +54 -0
  30. data/lib/pg_multitenant_schemas/migration_status_reporter.rb +65 -0
  31. data/lib/pg_multitenant_schemas/migrator.rb +89 -0
  32. data/lib/pg_multitenant_schemas/schema_switcher.rb +40 -66
  33. data/lib/pg_multitenant_schemas/tasks/advanced_tasks.rake +21 -0
  34. data/lib/pg_multitenant_schemas/tasks/basic_tasks.rake +20 -0
  35. data/lib/pg_multitenant_schemas/tasks/pg_multitenant_schemas.rake +53 -143
  36. data/lib/pg_multitenant_schemas/tasks/tenant_tasks.rake +65 -0
  37. data/lib/pg_multitenant_schemas/tenant_task_helpers.rb +102 -0
  38. data/lib/pg_multitenant_schemas/version.rb +1 -1
  39. data/lib/pg_multitenant_schemas.rb +10 -5
  40. data/pg_multitenant_schemas.gemspec +10 -9
  41. data/pre-push-check.sh +95 -0
  42. data/rails_integration/app/controllers/application_controller.rb +6 -0
  43. data/rails_integration/app/models/tenant.rb +6 -0
  44. data/test-github-setup.sh +85 -0
  45. data/validate-github-commands.sh +47 -0
  46. metadata +49 -17
data/docs/testing.md ADDED
@@ -0,0 +1,358 @@
1
+ # RSpec Testing Guide - PgMultitenantSchemas
2
+
3
+ ## ๐Ÿ“‹ **Overview**
4
+
5
+ This document provides comprehensive information about the RSpec test suite for the PgMultitenantSchemas gem, including unit tests, integration tests, and testing best practices.
6
+
7
+ ## ๐Ÿ—๏ธ **Test Architecture**
8
+
9
+ ### **Test Categories**
10
+
11
+ The test suite is organized into two main categories:
12
+
13
+ #### **1. Unit Tests** (Fast, Isolated)
14
+ - **Location**: `spec/*_spec.rb`
15
+ - **Execution**: Default `bundle exec rspec`
16
+ - **Purpose**: Test individual components in isolation
17
+ - **Database**: Uses mocked connections where possible
18
+ - **Speed**: Very fast (~0.03-0.16 seconds)
19
+
20
+ #### **2. Integration Tests** (Comprehensive, Database)
21
+ - **Location**: Tagged with `:integration`
22
+ - **Execution**: `bundle exec rspec --tag integration`
23
+ - **Purpose**: Test real PostgreSQL interactions and multi-schema operations
24
+ - **Database**: Requires running PostgreSQL instance
25
+ - **Speed**: Moderate (~0.67-1.17 seconds)
26
+
27
+ ## โš™๏ธ **Configuration**
28
+
29
+ ### **RSpec Configuration Files**
30
+
31
+ #### **`.rspec`**
32
+ ```plaintext
33
+ --format documentation
34
+ --color
35
+ --require spec_helper
36
+ --tag ~integration # Exclude integration tests by default
37
+ ```
38
+
39
+ #### **`spec/spec_helper.rb`**
40
+ ```ruby
41
+ require "rspec"
42
+ require "pg_multitenant_schemas"
43
+
44
+ RSpec.configure do |config|
45
+ config.example_status_persistence_file_path = ".rspec_status"
46
+ config.disable_monkey_patching!
47
+ config.expect_with :rspec do |c|
48
+ c.syntax = :expect
49
+ end
50
+ end
51
+ ```
52
+
53
+ ### **Environment Variables**
54
+
55
+ Integration tests use these environment variables for PostgreSQL connection:
56
+
57
+ ```bash
58
+ PG_HOST=localhost # PostgreSQL host
59
+ PG_PORT=5432 # PostgreSQL port
60
+ PG_TEST_DATABASE=pg_multitenant_test # Test database name
61
+ PG_USER=postgres # Database user
62
+ PG_PASSWORD= # Database password (empty by default)
63
+ ```
64
+
65
+ ## ๐Ÿงช **Test Suite Structure**
66
+
67
+ ### **Unit Tests (65 examples)**
68
+
69
+ | **Test File** | **Component** | **Purpose** |
70
+ |---------------|---------------|-------------|
71
+ | `configuration_spec.rb` | Configuration | Test configuration options and validation |
72
+ | `context_spec.rb` | Context | Test tenant/schema context management |
73
+ | `schema_switcher_spec.rb` | SchemaSwitcher | Test schema operations (mocked) |
74
+ | `tenant_resolver_spec.rb` | TenantResolver | Test subdomain extraction and tenant resolution |
75
+ | `pg_multitenant_schemas_spec.rb` | Main Module | Test gem version and basic functionality |
76
+ | `edge_cases_spec.rb` | Edge Cases | Test error handling and edge cases |
77
+ | `performance_spec.rb` | Performance | Test memory usage and thread safety |
78
+ | `integration_spec.rb` | Integration | Test component interactions (mocked) |
79
+ | `errors_spec.rb` | Error Classes | Test custom error definitions |
80
+ | `rails_integration/tenant_spec.rb` | Rails Integration | Test Rails model and validation integration |
81
+
82
+ ### **Integration Tests (21 examples)**
83
+
84
+ | **Test File** | **Component** | **Purpose** |
85
+ |---------------|---------------|-------------|
86
+ | `postgresql_integration_spec.rb` | PostgreSQL | Real database schema operations |
87
+ | `multiple_schemas_integration_spec.rb` | Multi-Schema | Complex schema interactions and isolation |
88
+ | `multiple_schemas_database_spec.rb` | Database Ops | Bulk operations and schema management |
89
+ | `multiple_tenants_context_spec.rb` | Context | Multi-tenant context switching |
90
+
91
+ ## ๐Ÿš€ **Running Tests**
92
+
93
+ ### **Unit Tests Only** (Default, Fast)
94
+ ```bash
95
+ # Run all unit tests (excludes integration)
96
+ bundle exec rspec
97
+
98
+ # Run specific unit test file
99
+ bundle exec rspec spec/configuration_spec.rb
100
+
101
+ # Run with verbose output
102
+ bundle exec rspec --format documentation
103
+ ```
104
+
105
+ ### **Integration Tests Only** (Requires PostgreSQL)
106
+ ```bash
107
+ # Run all integration tests
108
+ bundle exec rspec --tag integration
109
+
110
+ # Run with documentation format
111
+ bundle exec rspec --tag integration --format documentation
112
+
113
+ # Run specific integration test
114
+ bundle exec rspec spec/postgresql_integration_spec.rb
115
+ ```
116
+
117
+ ### **All Tests** (Complete Test Suite)
118
+ ```bash
119
+ # Run both unit and integration tests
120
+ bundle exec rspec --tag integration spec/ && bundle exec rspec
121
+
122
+ # Alternative: Run all tests including integration
123
+ bundle exec rspec --no-tag
124
+ ```
125
+
126
+ ## ๐Ÿ” **Test Categories Deep Dive**
127
+
128
+ ### **Unit Tests Details**
129
+
130
+ #### **Configuration Tests**
131
+ ```ruby
132
+ # Tests configuration object behavior
133
+ RSpec.describe PgMultitenantSchemas::Configuration do
134
+ describe "#initialize" do
135
+ it "sets default values"
136
+ end
137
+
138
+ describe "#connection_class=" do
139
+ it "allows setting connection class"
140
+ end
141
+ end
142
+ ```
143
+
144
+ #### **Context Management Tests**
145
+ ```ruby
146
+ # Tests tenant/schema context switching
147
+ RSpec.describe PgMultitenantSchemas::Context do
148
+ describe ".current_schema" do
149
+ it "defaults to public schema"
150
+ end
151
+
152
+ describe ".current_tenant=" do
153
+ it "sets the current tenant"
154
+ end
155
+ end
156
+ ```
157
+
158
+ #### **Edge Cases and Error Handling**
159
+ ```ruby
160
+ # Tests robust error handling
161
+ RSpec.describe "Edge Cases and Error Handling" do
162
+ describe "schema name validation" do
163
+ it "handles whitespace-only schema names"
164
+ it "handles special characters in schema names"
165
+ it "handles unicode characters"
166
+ end
167
+ end
168
+ ```
169
+
170
+ ### **Integration Tests Details**
171
+
172
+ #### **PostgreSQL Integration Tests**
173
+ ```ruby
174
+ # Real database operations
175
+ RSpec.describe "PostgreSQL Integration Tests", :integration do
176
+ describe "schema creation" do
177
+ it "actually creates a schema in PostgreSQL"
178
+ end
179
+
180
+ describe "schema switching" do
181
+ it "actually switches the search_path"
182
+ end
183
+ end
184
+ ```
185
+
186
+ #### **Multiple Schemas Integration**
187
+ ```ruby
188
+ # Complex multi-tenant scenarios
189
+ RSpec.describe "Multiple Schemas Integration Tests", :integration do
190
+ describe "multiple tenant schemas" do
191
+ it "creates multiple schemas successfully"
192
+ it "maintains data isolation between schemas"
193
+ it "handles concurrent schema access safely"
194
+ end
195
+ end
196
+ ```
197
+
198
+ ## ๐Ÿ› ๏ธ **Database Setup for Integration Tests**
199
+
200
+ ### **Prerequisites**
201
+
202
+ 1. **PostgreSQL Running**: Ensure PostgreSQL is running locally or accessible
203
+ 2. **Test Database**: Create a test database (usually `pg_multitenant_test`)
204
+ 3. **Permissions**: Ensure test user has schema creation/deletion permissions
205
+
206
+ ### **Setup Commands**
207
+
208
+ ```bash
209
+ # Create test database (PostgreSQL)
210
+ createdb pg_multitenant_test
211
+
212
+ # Or using psql
213
+ psql -c "CREATE DATABASE pg_multitenant_test;"
214
+
215
+ # Grant necessary permissions
216
+ psql -d pg_multitenant_test -c "GRANT ALL PRIVILEGES ON DATABASE pg_multitenant_test TO postgres;"
217
+ ```
218
+
219
+ ### **Connection Configuration**
220
+
221
+ Integration tests automatically handle connection setup:
222
+
223
+ ```ruby
224
+ let(:db_config) do
225
+ {
226
+ host: ENV["PG_HOST"] || "localhost",
227
+ port: ENV["PG_PORT"] || 5432,
228
+ dbname: ENV["PG_TEST_DATABASE"] || "pg_multitenant_test",
229
+ user: ENV["PG_USER"] || "postgres",
230
+ password: ENV["PG_PASSWORD"] || ""
231
+ }
232
+ end
233
+ ```
234
+
235
+ ## ๐Ÿงน **Test Cleanup and Isolation**
236
+
237
+ ### **Automatic Cleanup**
238
+
239
+ Integration tests include comprehensive cleanup:
240
+
241
+ ```ruby
242
+ after do
243
+ # Clean up test schemas
244
+ ["tenant_a", "tenant_b", "tenant_c", "public_test"].each do |schema|
245
+ PgMultitenantSchemas::SchemaSwitcher.drop_schema(schema, cascade: true)
246
+ rescue => e
247
+ # Log cleanup errors but don't fail tests
248
+ end
249
+
250
+ # Reset to public schema
251
+ PgMultitenantSchemas::SchemaSwitcher.reset_to_public_schema
252
+ end
253
+ ```
254
+
255
+ ### **Schema Isolation**
256
+
257
+ Each test creates and destroys its own schemas:
258
+
259
+ ```ruby
260
+ let(:tenants) { ["tenant_a", "tenant_b", "tenant_c"] }
261
+
262
+ before do
263
+ # Ensure clean state
264
+ tenants.each { |t| PgMultitenantSchemas::SchemaSwitcher.create_schema(t) }
265
+ end
266
+ ```
267
+
268
+ ## ๐Ÿ“Š **Test Coverage and Quality**
269
+
270
+ ### **Current Test Metrics**
271
+
272
+ - **Total Examples**: 86 (65 unit + 21 integration)
273
+ - **Failures**: 0
274
+ - **Coverage Areas**:
275
+ - โœ… Configuration management
276
+ - โœ… Schema operations
277
+ - โœ… Tenant resolution
278
+ - โœ… Context switching
279
+ - โœ… Error handling
280
+ - โœ… Performance characteristics
281
+ - โœ… Thread safety
282
+ - โœ… Rails integration
283
+ - โœ… Multi-schema scenarios
284
+ - โœ… Concurrent access patterns
285
+
286
+ ### **Test Quality Features**
287
+
288
+ - **Fast Unit Tests**: Complete in ~0.03 seconds
289
+ - **Comprehensive Integration**: Real PostgreSQL testing
290
+ - **Thread Safety**: Multi-threaded scenario testing
291
+ - **Memory Leak Detection**: Performance monitoring
292
+ - **Edge Case Coverage**: Unicode, special characters, malformed data
293
+ - **Error Scenario Testing**: Connection failures, invalid schemas
294
+
295
+ ## ๐Ÿ”ง **Debugging Tests**
296
+
297
+ ### **Common Issues and Solutions**
298
+
299
+ #### **PostgreSQL Connection Issues**
300
+ ```bash
301
+ # Check if PostgreSQL is running
302
+ pg_isready
303
+
304
+ # Check connection with custom settings
305
+ PG_HOST=localhost PG_USER=myuser bundle exec rspec --tag integration
306
+ ```
307
+
308
+ #### **Schema Cleanup Issues**
309
+ ```ruby
310
+ # Manual cleanup if tests leave artifacts
311
+ psql -d pg_multitenant_test -c "DROP SCHEMA IF EXISTS tenant_a CASCADE;"
312
+ ```
313
+
314
+ #### **Verbose Test Output**
315
+ ```bash
316
+ # Run with detailed output for debugging
317
+ bundle exec rspec --format documentation --color
318
+
319
+ # Run specific failing test
320
+ bundle exec rspec spec/multiple_schemas_integration_spec.rb:90 --format documentation
321
+ ```
322
+
323
+ ### **Test Development Tips**
324
+
325
+ 1. **Unit Test First**: Write fast unit tests before integration tests
326
+ 2. **Mock External Dependencies**: Use mocks for database connections in unit tests
327
+ 3. **Clean Isolation**: Ensure each test cleans up after itself
328
+ 4. **Descriptive Names**: Use clear, descriptive test names
329
+ 5. **Edge Cases**: Test boundary conditions and error scenarios
330
+
331
+ ## ๐Ÿ“š **Related Documentation**
332
+
333
+ - **[Architecture Overview](README.md)**: Understanding the overall gem structure
334
+ - **[Configuration Guide](configuration.md)**: Test configuration options
335
+ - **[Rails Integration](rails_integration.md)**: Framework-specific testing patterns
336
+ - **[Error Handling](errors.md)**: Error testing strategies
337
+
338
+ ## ๐ŸŽฏ **Test Development Workflow**
339
+
340
+ ### **Adding New Tests**
341
+
342
+ 1. **Identify Test Type**: Unit vs Integration
343
+ 2. **Create Test File**: Follow naming convention `*_spec.rb`
344
+ 3. **Add Appropriate Tags**: Use `:integration` for database tests
345
+ 4. **Include Setup/Teardown**: Proper before/after hooks
346
+ 5. **Test Edge Cases**: Include error scenarios
347
+ 6. **Run Test Suite**: Verify no regressions
348
+
349
+ ### **Best Practices**
350
+
351
+ - **Keep Unit Tests Fast**: Avoid database calls in unit tests
352
+ - **Use Descriptive Contexts**: Group related tests logically
353
+ - **Test Public APIs**: Focus on public interface testing
354
+ - **Mock External Services**: Isolate component under test
355
+ - **Include Performance Tests**: Monitor resource usage
356
+ - **Document Complex Scenarios**: Comment non-obvious test logic
357
+
358
+ This comprehensive test suite ensures the PgMultitenantSchemas gem is robust, reliable, and ready for production use across various scenarios and environments.
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Context Management Example
5
+ # Demonstrates thread-safe tenant context management
6
+
7
+ require_relative "../lib/pg_multitenant_schemas"
8
+
9
+ puts "๐Ÿงต PG Multitenant Schemas - Context Management Example"
10
+ puts "======================================================"
11
+
12
+ # Mock tenant class for demonstration
13
+ class MockTenant
14
+ attr_reader :id, :subdomain, :name
15
+
16
+ def initialize(id, subdomain, name)
17
+ @id = id
18
+ @subdomain = subdomain
19
+ @name = name
20
+ end
21
+
22
+ def to_s
23
+ subdomain
24
+ end
25
+ end
26
+
27
+ # Create mock tenants
28
+ tenant_a = MockTenant.new(1, "acme_corp", "ACME Corporation")
29
+ tenant_b = MockTenant.new(2, "beta_inc", "Beta Inc")
30
+
31
+ # Example 1: Basic Context Management
32
+ puts "\n๐Ÿ“‹ Example 1: Basic Context Management"
33
+ puts "--------------------------------------"
34
+
35
+ # Check initial state
36
+ puts "Initial context:"
37
+ puts " Current tenant: #{PgMultitenantSchemas::Context.current_tenant || "none"}"
38
+ puts " Current schema: #{PgMultitenantSchemas::Context.current_schema}"
39
+
40
+ # Switch to tenant A
41
+ puts "\nSwitching to tenant A (#{tenant_a.subdomain}):"
42
+ PgMultitenantSchemas::Context.switch_to_tenant(tenant_a)
43
+ puts " Current tenant: #{PgMultitenantSchemas::Context.current_tenant}"
44
+ puts " Current schema: #{PgMultitenantSchemas::Context.current_schema}"
45
+
46
+ # Switch to tenant B
47
+ puts "\nSwitching to tenant B (#{tenant_b.subdomain}):"
48
+ PgMultitenantSchemas::Context.switch_to_tenant(tenant_b)
49
+ puts " Current tenant: #{PgMultitenantSchemas::Context.current_tenant}"
50
+ puts " Current schema: #{PgMultitenantSchemas::Context.current_schema}"
51
+
52
+ # Reset context
53
+ puts "\nResetting context:"
54
+ PgMultitenantSchemas::Context.reset!
55
+ puts " Current tenant: #{PgMultitenantSchemas::Context.current_tenant || "none"}"
56
+ puts " Current schema: #{PgMultitenantSchemas::Context.current_schema}"
57
+
58
+ # Example 2: Block-Based Context Management
59
+ puts "\n๐Ÿ”„ Example 2: Block-Based Context Management"
60
+ puts "--------------------------------------------"
61
+
62
+ puts "Before block - Current schema: #{PgMultitenantSchemas::Context.current_schema}"
63
+
64
+ PgMultitenantSchemas::Context.with_tenant(tenant_a) do
65
+ puts "Inside block - Current schema: #{PgMultitenantSchemas::Context.current_schema}"
66
+ puts "Inside block - Current tenant: #{PgMultitenantSchemas::Context.current_tenant}"
67
+
68
+ # Simulate some work in tenant context
69
+ puts " ๐Ÿ”ง Performing operations for #{tenant_a.name}..."
70
+ sleep(0.1) # Simulate work
71
+ end
72
+
73
+ puts "After block - Current schema: #{PgMultitenantSchemas::Context.current_schema}"
74
+ puts "After block - Current tenant: #{PgMultitenantSchemas::Context.current_tenant || "none"}"
75
+
76
+ # Example 3: Nested Context Management
77
+ puts "\n๐Ÿช† Example 3: Nested Context Management"
78
+ puts "---------------------------------------"
79
+
80
+ puts "Starting nested context example..."
81
+
82
+ PgMultitenantSchemas::Context.with_tenant(tenant_a) do
83
+ puts "Level 1 - In tenant A (#{PgMultitenantSchemas::Context.current_schema})"
84
+
85
+ PgMultitenantSchemas::Context.with_tenant(tenant_b) do
86
+ puts " Level 2 - In tenant B (#{PgMultitenantSchemas::Context.current_schema})"
87
+
88
+ # Even deeper nesting
89
+ PgMultitenantSchemas::Context.with_tenant("custom_schema") do
90
+ puts " Level 3 - In custom schema (#{PgMultitenantSchemas::Context.current_schema})"
91
+ end
92
+
93
+ puts " Level 2 - Back in tenant B (#{PgMultitenantSchemas::Context.current_schema})"
94
+ end
95
+
96
+ puts "Level 1 - Back in tenant A (#{PgMultitenantSchemas::Context.current_schema})"
97
+ end
98
+
99
+ puts "Nested context complete - Current schema: #{PgMultitenantSchemas::Context.current_schema}"
100
+
101
+ # Example 4: Error Handling in Context
102
+ puts "\n๐Ÿšจ Example 4: Error Handling in Context"
103
+ puts "---------------------------------------"
104
+
105
+ puts "Testing error handling with context restoration..."
106
+
107
+ begin
108
+ PgMultitenantSchemas::Context.with_tenant(tenant_a) do
109
+ puts "In tenant A context: #{PgMultitenantSchemas::Context.current_schema}"
110
+
111
+ # Simulate an error
112
+ raise StandardError, "Simulated error!"
113
+ end
114
+ rescue StandardError => e
115
+ puts "Caught error: #{e.message}"
116
+ end
117
+
118
+ puts "After error - Current schema: #{PgMultitenantSchemas::Context.current_schema}"
119
+ puts "โœ… Context properly restored after error!"
120
+
121
+ # Example 5: Thread Safety Demonstration
122
+ puts "\n๐Ÿงต Example 5: Thread Safety Demonstration"
123
+ puts "-----------------------------------------"
124
+
125
+ threads = []
126
+ results = {}
127
+
128
+ # Create multiple threads with different tenant contexts
129
+ [tenant_a, tenant_b].each_with_index do |tenant, index|
130
+ threads << Thread.new do
131
+ thread_id = "Thread-#{index + 1}"
132
+ results[thread_id] = []
133
+
134
+ PgMultitenantSchemas::Context.with_tenant(tenant) do
135
+ 5.times do |i|
136
+ current_schema = PgMultitenantSchemas::Context.current_schema
137
+ current_tenant = PgMultitenantSchemas::Context.current_tenant
138
+
139
+ results[thread_id] << {
140
+ iteration: i + 1,
141
+ schema: current_schema,
142
+ tenant: current_tenant&.subdomain,
143
+ thread: Thread.current.object_id
144
+ }
145
+
146
+ sleep(0.01) # Small delay to allow thread interleaving
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ # Wait for all threads to complete
153
+ threads.each(&:join)
154
+
155
+ # Display results
156
+ puts "Thread safety results:"
157
+ results.each do |thread_id, iterations|
158
+ puts "#{thread_id}:"
159
+ iterations.each do |result|
160
+ puts " Iteration #{result[:iteration]}: #{result[:schema]} (tenant: #{result[:tenant]})"
161
+ end
162
+ end
163
+
164
+ puts "โœ… Each thread maintained its own tenant context!"
165
+
166
+ # Example 6: Schema Management Through Context
167
+ puts "\n๐Ÿ”ง Example 6: Schema Management Through Context"
168
+ puts "----------------------------------------------"
169
+
170
+ test_tenant = MockTenant.new(99, "test_tenant", "Test Tenant")
171
+
172
+ begin
173
+ # Create tenant schema
174
+ puts "Creating schema for tenant: #{test_tenant.subdomain}"
175
+ PgMultitenantSchemas::Context.create_tenant_schema(test_tenant)
176
+ puts "โœ… Schema created successfully"
177
+
178
+ # Use the tenant context
179
+ PgMultitenantSchemas::Context.with_tenant(test_tenant) do
180
+ puts "Operating in tenant schema: #{PgMultitenantSchemas::Context.current_schema}"
181
+ # Simulate tenant operations
182
+ end
183
+
184
+ # Clean up
185
+ puts "Cleaning up test schema..."
186
+ PgMultitenantSchemas::Context.drop_tenant_schema(test_tenant)
187
+ puts "โœ… Schema cleaned up successfully"
188
+ rescue PgMultitenantSchemas::SchemaError => e
189
+ puts "โŒ Schema operation failed: #{e.message}"
190
+ end
191
+
192
+ puts "\nโœจ Context management example completed!"
193
+ puts "\n๐Ÿ“– Key Takeaways:"
194
+ puts " โ€ข Context is automatically restored after blocks"
195
+ puts " โ€ข Each thread maintains independent tenant context"
196
+ puts " โ€ข Nested contexts work correctly with proper restoration"
197
+ puts " โ€ข Error handling doesn't break context restoration"
198
+ puts " โ€ข Context can handle both tenant objects and schema strings"
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Example script demonstrating the new migration workflow
5
+ # This shows how the simplified migration system works
6
+
7
+ require_relative "../lib/pg_multitenant_schemas"
8
+
9
+ puts "๐Ÿš€ PG Multitenant Schemas - Migration Workflow Example"
10
+ puts "======================================================"
11
+
12
+ # Example 1: Setup new tenant with full migration
13
+ puts "\n๐Ÿ“‹ Example 1: Setting up a new tenant"
14
+ puts "Command: PgMultitenantSchemas::Migrator.setup_tenant('example_corp')"
15
+ puts "Result: Creates schema + runs all migrations automatically"
16
+
17
+ # Example 2: Migration status check
18
+ puts "\n๐Ÿ“Š Example 2: Checking migration status"
19
+ puts "Command: PgMultitenantSchemas::Migrator.migration_status"
20
+ puts "Result: Shows status across all tenant schemas"
21
+
22
+ # Example 3: Bulk migration
23
+ puts "\n๐Ÿ”„ Example 3: Migrate all tenants"
24
+ puts "Command: PgMultitenantSchemas::Migrator.migrate_all"
25
+ puts "Result: Runs pending migrations across all tenant schemas"
26
+
27
+ # Example 4: Individual tenant migration
28
+ puts "\n๐ŸŽฏ Example 4: Migrate specific tenant"
29
+ puts "Command: PgMultitenantSchemas::Migrator.migrate_tenant('acme_corp')"
30
+ puts "Result: Runs migrations only for acme_corp schema"
31
+
32
+ # Example 5: Create tenant with attributes
33
+ puts "\n๐Ÿข Example 5: Create tenant with attributes"
34
+ puts "Command: PgMultitenantSchemas::Migrator.create_tenant_with_schema({subdomain: 'newco', name: 'New Company'})"
35
+ puts "Result: Creates Tenant record + schema + runs migrations"
36
+
37
+ puts "\nโœจ Key Benefits:"
38
+ puts " โ€ข Single command migration across all tenants"
39
+ puts " โ€ข Automatic error handling per tenant"
40
+ puts " โ€ข Progress tracking and status reporting"
41
+ puts " โ€ข Simplified rake task interface"
42
+ puts " โ€ข Programmatic API for custom workflows"
43
+
44
+ puts "\n๐Ÿ”ง Rake Task Examples:"
45
+ puts " rails tenants:migrate # Migrate all tenants"
46
+ puts " rails tenants:create[newco] # Setup new tenant"
47
+ puts " rails tenants:status # Check migration status"
48
+ puts " rails tenants:list # List all tenant schemas"
49
+
50
+ puts "\n๐Ÿ“– See README.md for complete documentation"