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
data/docs/migrator.md ADDED
@@ -0,0 +1,291 @@
1
+ # Migrator - Automated Migration Management
2
+
3
+ **File**: `lib/pg_multitenant_schemas/migrator.rb`
4
+
5
+ ## 📋 Overview
6
+
7
+ The `Migrator` class provides comprehensive automated migration management for multi-tenant applications. It handles running migrations across all tenant schemas, setting up new tenants, and tracking migration status.
8
+
9
+ ## 🎯 Purpose
10
+
11
+ - **Bulk Migration**: Run migrations across all tenant schemas with single command
12
+ - **Tenant Setup**: Automated tenant creation with schema and migrations
13
+ - **Status Tracking**: Monitor migration status across all tenants
14
+ - **Error Resilience**: Handle migration failures gracefully per tenant
15
+ - **Progress Reporting**: Detailed feedback during migration operations
16
+
17
+ ## 🔧 Key Methods
18
+
19
+ ### Core Migration Operations
20
+
21
+ ```ruby
22
+ # Migrate all tenant schemas
23
+ Migrator.migrate_all
24
+
25
+ # Migrate specific tenant
26
+ Migrator.migrate_tenant('acme_corp')
27
+
28
+ # Check migration status across all tenants
29
+ Migrator.migration_status
30
+
31
+ # Setup new tenant (create schema + run migrations)
32
+ Migrator.setup_tenant('new_tenant')
33
+ ```
34
+
35
+ ### Tenant Management
36
+
37
+ ```ruby
38
+ # Setup all existing tenants
39
+ Migrator.setup_all_tenants
40
+
41
+ # Create tenant with attributes and schema
42
+ Migrator.create_tenant_with_schema({
43
+ subdomain: 'acme',
44
+ name: 'ACME Corporation'
45
+ })
46
+
47
+ # Rollback specific tenant
48
+ Migrator.rollback_tenant('tenant_name', steps: 2)
49
+ ```
50
+
51
+ ## 🏗️ Implementation Details
52
+
53
+ ### Migration Execution Flow
54
+
55
+ ```ruby
56
+ def migrate_all
57
+ puts "🚀 Starting migration for all tenant schemas..."
58
+
59
+ tenant_schemas.each do |schema|
60
+ puts "📦 Migrating schema: #{schema}"
61
+
62
+ migrate_tenant(schema)
63
+ end
64
+
65
+ puts "✅ Migration completed for all schemas"
66
+ end
67
+ ```
68
+
69
+ ### Error Handling Strategy
70
+
71
+ The Migrator implements robust error handling:
72
+
73
+ - **Per-Tenant Isolation**: Failures in one tenant don't affect others
74
+ - **Detailed Error Reporting**: Specific error messages per tenant
75
+ - **Continue on Error**: Migration continues for remaining tenants
76
+ - **Transaction Safety**: Each tenant migration is self-contained
77
+
78
+ ### Progress Tracking
79
+
80
+ ```ruby
81
+ def migration_status
82
+ puts "📊 Migration Status Report"
83
+
84
+ tenant_schemas.each do |schema|
85
+ pending = pending_migrations_for_schema(schema)
86
+
87
+ if pending.empty?
88
+ puts "▸ #{schema}: ✅ Up to date"
89
+ else
90
+ puts "▸ #{schema}: ⚠️ #{pending.count} pending migrations"
91
+ end
92
+ end
93
+ end
94
+ ```
95
+
96
+ ## 🔄 Usage Patterns
97
+
98
+ ### Daily Operations
99
+
100
+ ```ruby
101
+ # Check what needs migration
102
+ PgMultitenantSchemas::Migrator.migration_status
103
+
104
+ # Run migrations across all tenants
105
+ PgMultitenantSchemas::Migrator.migrate_all
106
+
107
+ # Setup new tenant
108
+ PgMultitenantSchemas::Migrator.setup_tenant('new_client')
109
+ ```
110
+
111
+ ### Deployment Workflow
112
+
113
+ ```ruby
114
+ # In deployment script
115
+ namespace :deploy do
116
+ task :migrate_tenants do
117
+ PgMultitenantSchemas::Migrator.migrate_all
118
+ end
119
+ end
120
+ ```
121
+
122
+ ### New Tenant Onboarding
123
+
124
+ ```ruby
125
+ # Complete tenant setup
126
+ tenant_attributes = {
127
+ subdomain: 'newco',
128
+ name: 'New Company Ltd',
129
+ domain: 'newco.com'
130
+ }
131
+
132
+ tenant = PgMultitenantSchemas::Migrator.create_tenant_with_schema(tenant_attributes)
133
+ puts "✅ Tenant #{tenant.subdomain} ready for use"
134
+ ```
135
+
136
+ ### Rollback Operations
137
+
138
+ ```ruby
139
+ # Rollback specific tenant
140
+ PgMultitenantSchemas::Migrator.rollback_tenant('acme_corp', steps: 1)
141
+
142
+ # Check status after rollback
143
+ PgMultitenantSchemas::Migrator.migration_status
144
+ ```
145
+
146
+ ## 🎛️ Configuration Integration
147
+
148
+ The Migrator respects global configuration:
149
+
150
+ ```ruby
151
+ PgMultitenantSchemas.configure do |config|
152
+ config.default_schema = 'public'
153
+ config.tenant_model = 'Tenant'
154
+ config.connection_class = 'ApplicationRecord'
155
+ end
156
+ ```
157
+
158
+ ## 📊 Status Reporting
159
+
160
+ ### Migration Status Output
161
+
162
+ ```
163
+ 📊 Migration Status Report
164
+ ▸ acme_corp: ✅ Up to date (5 migrations)
165
+ ▸ beta_corp: ⚠️ 2 pending migrations
166
+ - 20241201120000_add_feature_flags
167
+ - 20241202100000_update_user_fields
168
+ ▸ demo_corp: ✅ Up to date (5 migrations)
169
+
170
+ 📈 Overall: 2/3 tenants current, 2 migrations pending
171
+ ```
172
+
173
+ ### Migration Progress Output
174
+
175
+ ```
176
+ 🚀 Starting migration for all tenant schemas...
177
+
178
+ 📦 Migrating schema: acme_corp
179
+ ✓ Running migration 20241201120000_add_feature_flags
180
+ ✓ Running migration 20241202100000_update_user_fields
181
+ ✅ Completed migration for acme_corp
182
+
183
+ 📦 Migrating schema: beta_corp
184
+ ✓ Running migration 20241201120000_add_feature_flags
185
+ ✗ Error in migration 20241202100000_update_user_fields: column already exists
186
+ ⚠️ Continuing with next tenant...
187
+
188
+ ✅ Migration completed for all schemas
189
+ 📊 Summary: 1/2 tenants migrated successfully
190
+ ```
191
+
192
+ ## 🔍 Advanced Features
193
+
194
+ ### Custom Migration Paths
195
+
196
+ ```ruby
197
+ # Override migration paths if needed
198
+ class CustomMigrator < PgMultitenantSchemas::Migrator
199
+ private
200
+
201
+ def migration_paths
202
+ [
203
+ Rails.root.join('db', 'migrate'),
204
+ Rails.root.join('db', 'tenant_migrations')
205
+ ]
206
+ end
207
+ end
208
+ ```
209
+
210
+ ### Migration Callbacks
211
+
212
+ ```ruby
213
+ # Add hooks for migration events
214
+ module MigrationHooks
215
+ def self.before_tenant_migration(schema_name)
216
+ Rails.logger.info "Starting migration for #{schema_name}"
217
+ end
218
+
219
+ def self.after_tenant_migration(schema_name, success)
220
+ status = success ? "SUCCESS" : "FAILED"
221
+ Rails.logger.info "Migration for #{schema_name}: #{status}"
222
+ end
223
+ end
224
+ ```
225
+
226
+ ### Batch Processing
227
+
228
+ ```ruby
229
+ # Process tenants in batches for large installations
230
+ def migrate_all_batched(batch_size: 10)
231
+ tenant_schemas.each_slice(batch_size) do |batch|
232
+ batch.each { |schema| migrate_tenant(schema) }
233
+ sleep(1) # Brief pause between batches
234
+ end
235
+ end
236
+ ```
237
+
238
+ ## 🚨 Important Considerations
239
+
240
+ ### Performance
241
+
242
+ - **Parallel Processing**: Consider parallelization for large tenant counts
243
+ - **Resource Usage**: Monitor database connections during bulk operations
244
+ - **Timing**: Run during low-traffic periods for production
245
+
246
+ ### Data Integrity
247
+
248
+ - **Backup Strategy**: Ensure proper backups before major migrations
249
+ - **Testing**: Test migrations on staging environment with production data
250
+ - **Rollback Plan**: Have rollback procedures for failed migrations
251
+
252
+ ### Monitoring
253
+
254
+ - **Log Analysis**: Monitor migration logs for patterns and issues
255
+ - **Alert Setup**: Set up alerts for migration failures
256
+ - **Performance Metrics**: Track migration duration and resource usage
257
+
258
+ ## 🔧 Troubleshooting
259
+
260
+ ### Common Issues
261
+
262
+ **Migration Stuck**
263
+ ```ruby
264
+ # Check for long-running queries
265
+ ActiveRecord::Base.connection.execute("SELECT * FROM pg_stat_activity WHERE state = 'active'")
266
+ ```
267
+
268
+ **Schema Not Found**
269
+ ```ruby
270
+ # Verify schema exists
271
+ if !PgMultitenantSchemas::SchemaSwitcher.schema_exists?('tenant_name')
272
+ PgMultitenantSchemas::Migrator.setup_tenant('tenant_name')
273
+ end
274
+ ```
275
+
276
+ **Permission Errors**
277
+ ```ruby
278
+ # Check database permissions
279
+ ActiveRecord::Base.connection.execute("SELECT has_schema_privilege('tenant_schema', 'USAGE')")
280
+ ```
281
+
282
+ ## 🔗 Related Components
283
+
284
+ - **[SchemaSwitcher](schema_switcher.md)**: Core schema operations used by Migrator
285
+ - **[Context](context.md)**: Tenant context management during migrations
286
+ - **[Configuration](configuration.md)**: Migrator configuration options
287
+ - **[Rails Integration](rails_integration.md)**: Framework integration features
288
+
289
+ ## 📝 Examples
290
+
291
+ See [examples/migration_workflow.rb](../examples/) for complete usage examples and [rake tasks documentation](../lib/pg_multitenant_schemas/tasks/) for command-line usage.