sp-duh 2.0.6

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +661 -0
  3. data/README.md +2 -0
  4. data/Rakefile +32 -0
  5. data/config/i18n/i18n.xlsx +0 -0
  6. data/config/initializers/active_record/connection_adapters_postgre_sql_adapter.rb +165 -0
  7. data/config/initializers/active_record/migration_without_transaction.rb +4 -0
  8. data/config/initializers/active_record/migrator.rb +34 -0
  9. data/config/initializers/rails/generators.rb +13 -0
  10. data/config/jsonapi/settings.yml +14 -0
  11. data/config/locales/pt.yml +15 -0
  12. data/lib/generators/accounting_migration/accounting_migration_generator.rb +10 -0
  13. data/lib/generators/accounting_migration/templates/migration.rb +42 -0
  14. data/lib/generators/accounting_payroll_migration/accounting_payroll_migration_generator.rb +10 -0
  15. data/lib/generators/accounting_payroll_migration/templates/migration.rb +73 -0
  16. data/lib/generators/sharded_migration/sharded_migration_generator.rb +10 -0
  17. data/lib/generators/sharded_migration/templates/migration.rb +45 -0
  18. data/lib/sp-duh.rb +32 -0
  19. data/lib/sp/duh.rb +180 -0
  20. data/lib/sp/duh/adapters/pg/text_decoder/json.rb +15 -0
  21. data/lib/sp/duh/adapters/pg/text_encoder/json.rb +15 -0
  22. data/lib/sp/duh/db/transfer/backup.rb +71 -0
  23. data/lib/sp/duh/db/transfer/restore.rb +89 -0
  24. data/lib/sp/duh/engine.rb +35 -0
  25. data/lib/sp/duh/exceptions.rb +70 -0
  26. data/lib/sp/duh/i18n/excel_loader.rb +26 -0
  27. data/lib/sp/duh/jsonapi/adapters/base.rb +168 -0
  28. data/lib/sp/duh/jsonapi/adapters/db.rb +36 -0
  29. data/lib/sp/duh/jsonapi/adapters/raw_db.rb +77 -0
  30. data/lib/sp/duh/jsonapi/configuration.rb +167 -0
  31. data/lib/sp/duh/jsonapi/doc/apidoc_documentation_format_generator.rb +286 -0
  32. data/lib/sp/duh/jsonapi/doc/generator.rb +32 -0
  33. data/lib/sp/duh/jsonapi/doc/schema_catalog_helper.rb +97 -0
  34. data/lib/sp/duh/jsonapi/doc/victor_pinus_metadata_format_parser.rb +374 -0
  35. data/lib/sp/duh/jsonapi/exceptions.rb +56 -0
  36. data/lib/sp/duh/jsonapi/model/base.rb +25 -0
  37. data/lib/sp/duh/jsonapi/model/concerns/attributes.rb +94 -0
  38. data/lib/sp/duh/jsonapi/model/concerns/model.rb +42 -0
  39. data/lib/sp/duh/jsonapi/model/concerns/persistence.rb +221 -0
  40. data/lib/sp/duh/jsonapi/model/concerns/serialization.rb +59 -0
  41. data/lib/sp/duh/jsonapi/parameters.rb +44 -0
  42. data/lib/sp/duh/jsonapi/resource_publisher.rb +28 -0
  43. data/lib/sp/duh/jsonapi/service.rb +110 -0
  44. data/lib/sp/duh/migrations.rb +47 -0
  45. data/lib/sp/duh/migrations/migrator.rb +41 -0
  46. data/lib/sp/duh/repl.rb +193 -0
  47. data/lib/sp/duh/version.rb +25 -0
  48. data/lib/tasks/db_utils.rake +98 -0
  49. data/lib/tasks/doc.rake +27 -0
  50. data/lib/tasks/i18n.rake +23 -0
  51. data/lib/tasks/oauth.rake +29 -0
  52. data/lib/tasks/transfer.rake +48 -0
  53. data/lib/tasks/xls2jrxml.rake +15 -0
  54. data/test/jsonapi/server.rb +67 -0
  55. data/test/tasks/test.rake +10 -0
  56. metadata +170 -0
@@ -0,0 +1,2 @@
1
+ # sp-duh
2
+ Data Uber Helper
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env rake
2
+ #
3
+ # Copyright (c) 2011-2017 Cloudware S.A. All rights reserved.
4
+ #
5
+ # This file is part of sp-duh.
6
+ #
7
+ # sp-duh is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # sp-duh is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General Public License
18
+ # along with sp-duh. If not, see <http://www.gnu.org/licenses/>.
19
+ #
20
+ # encoding: utf-8
21
+ #
22
+ require "bundler/gem_tasks"
23
+ require 'sp-duh'
24
+
25
+ load 'lib/tasks/db_utils.rake'
26
+ load 'lib/tasks/i18n.rake'
27
+ load 'lib/tasks/xls2jrxml.rake'
28
+
29
+ # Allow calling common tasks either from the app (using its environment) or locally from the gem
30
+ # In this case, open the connection to the database
31
+ task :environment => :pg_connect do
32
+ end
Binary file
@@ -0,0 +1,165 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class PostgreSQLAdapter
4
+ def active?
5
+ true
6
+ end
7
+
8
+ def initialize_with_redis_connection(connection, logger, connection_parameters, config)
9
+ @redis_connection = Rails.application.redis.optimizations.instance_variable_get(:@data)
10
+ initialize_without_redis_connection(connection, logger, connection_parameters, config)
11
+ end
12
+
13
+ private
14
+
15
+ def configure_connection_with_mappings
16
+ # Build Ruby <-> PostgreSQL type mappings
17
+ results_map = PG::BasicTypeMapForResults.new(@connection, @redis_connection)
18
+ queries_map = PG::BasicTypeMapForQueries.new(@connection, @redis_connection)
19
+
20
+ # Add a decoder for the NUMERIC PostgreSQL data type
21
+ results_map.add_coder PG::TextDecoder::Float.new(oid: 1700, name: 'float8')
22
+ # Fix: Warning: no type cast defined for type "name" with oid 19. Please cast this type explicitly to TEXT to be safe for future changes.
23
+ results_map.add_coder PG::TextDecoder::String.new(oid: 19, name: 'text')
24
+ # Fix: Warning: no type cast defined for type "regproc" with oid 24. Please cast this type explicitly to TEXT to be safe for future changes.
25
+ results_map.add_coder PG::TextDecoder::String.new(oid: 24, name: 'text')
26
+
27
+ # Add decoders for the JSON and JSONB data types (using our custom decoder class)
28
+ results_map.add_coder SP::Duh::Adapters::PG::TextDecoder::Json.new(oid: 114, name: 'json')
29
+ results_map.add_coder SP::Duh::Adapters::PG::TextDecoder::Json.new(oid: 199, name: '_json')
30
+ results_map.add_coder SP::Duh::Adapters::PG::TextDecoder::Json.new(oid: 3802, name: 'jsonb')
31
+ results_map.add_coder SP::Duh::Adapters::PG::TextDecoder::Json.new(oid: 3807, name: '_jsonb')
32
+
33
+ # Fix: Remove decoder for Date and Timestamp
34
+ #<PG::TextDecoder::Date:0x0000000857dcf0 "date" oid=1082>,
35
+ results_map.rm_coder(0, 1082)
36
+
37
+ #<PG::TextDecoder::TimestampWithoutTimeZone:0x0000000857db38 "timestamp" oid=1114>,
38
+ results_map.rm_coder(0, 1114)
39
+
40
+ #<PG::TextDecoder::TimestampWithTimeZone:0x0000000857d958 "timestamptz" oid=1184>,
41
+ results_map.rm_coder(0, 1184)
42
+
43
+ #<PG::TextDecoder::Array:0x0000000868cdf8 "_timestamp" oid=1115>,
44
+ results_map.rm_coder(0, 1115)
45
+
46
+ #<PG::TextDecoder::Array:0x0000000868cd30 "_date" oid=1182>,
47
+ results_map.rm_coder(0, 1182)
48
+
49
+ #<PG::TextDecoder::Array:0x0000000868cc40 "_timestamptz" oid=1185>,
50
+ results_map.rm_coder(0, 1185)
51
+
52
+ # <PG::TextDecoder::Bytea:0x007f96afcc1aa8 "bytea" oid=17>,
53
+ results_map.rm_coder(0, 17)
54
+
55
+ # Set PostgreSQL type mappings
56
+ @connection.type_map_for_results = results_map
57
+ @connection.type_map_for_queries = queries_map
58
+
59
+ configure_connection_without_mappings
60
+ end
61
+
62
+ # Override methods to store catalog data in Redis
63
+ %w(column_definitions primary_key table_exists?).each do |method|
64
+ method_name, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
65
+
66
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
67
+ def #{method_name}_with_redis_cache#{punctuation}(table_name)
68
+ if !!@redis_connection
69
+ @redis_connection.get("postgresql:#{method_name}:\#{table_name}") || begin
70
+ @redis_connection.set("postgresql:#{method_name}:\#{table_name}", d = #{method_name}_without_redis_cache#{punctuation}(table_name)) ; d
71
+ end
72
+ else
73
+ #{method_name}_without_redis_cache#{punctuation}(table_name)
74
+ end
75
+ end
76
+
77
+ alias_method_chain :#{method}, :redis_cache
78
+ METHOD
79
+ end
80
+
81
+ def disable_referential_integrity_with_foreign_keys(&block)
82
+ if Rails.env.test?
83
+ transaction do
84
+ begin
85
+ execute "SET CONSTRAINTS ALL DEFERRED"
86
+ yield
87
+ ensure
88
+ execute "SET CONSTRAINTS ALL IMMEDIATE"
89
+ end
90
+ end
91
+ else
92
+ disable_referential_integrity_without_foreign_keys &block
93
+ end
94
+ end
95
+
96
+ alias_method_chain :configure_connection, :mappings
97
+ alias_method_chain :disable_referential_integrity, :foreign_keys
98
+ alias_method_chain :initialize, :redis_connection
99
+ end
100
+ end
101
+ end
102
+
103
+ # This module MUST be loaded before the #configure_connection_with_mappings method is called
104
+ module PG
105
+ class BasicTypeMapForResults
106
+ def initialize_with_redis_connection(connection, redis_connection = nil)
107
+ @redis_connection = redis_connection
108
+ initialize_without_redis_connection connection
109
+ end
110
+
111
+ alias_method_chain :initialize, :redis_connection
112
+ end
113
+
114
+ class BasicTypeMapForQueries
115
+ def initialize_with_redis_connection(connection, redis_connection = nil)
116
+ @redis_connection = redis_connection
117
+ initialize_without_redis_connection connection
118
+ end
119
+
120
+ alias_method_chain :initialize, :redis_connection
121
+ end
122
+
123
+ module BasicTypeRegistry
124
+
125
+ private
126
+
127
+ def build_coder_maps(connection)
128
+ if !!@redis_connection
129
+ @redis_connection.get('postgresql:coder-maps') || begin
130
+ @redis_connection.set('postgresql:coder-maps', m = get_coder_maps_from_database(connection)) ; m
131
+ end
132
+ else
133
+ get_coder_maps_from_database(connection)
134
+ end
135
+ end
136
+
137
+ def get_coder_maps_from_database(connection)
138
+ result = connection.exec(if supports_ranges?(connection)
139
+ <<-SQL
140
+ SELECT n.nspname, t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype
141
+ FROM pg_type as t
142
+ LEFT JOIN pg_range as r ON oid = rngtypid
143
+ LEFT JOIN pg_namespace n ON n.oid = t.typnamespace
144
+ WHERE n.nspname IN ('pg_catalog', 'public')
145
+ SQL
146
+ else
147
+ <<-SQL
148
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput
149
+ FROM pg_type as t
150
+ SQL
151
+ end)
152
+
153
+ [
154
+ [0, :encoder, PG::TextEncoder::Array],
155
+ [0, :decoder, PG::TextDecoder::Array],
156
+ [1, :encoder, nil],
157
+ [1, :decoder, nil],
158
+ ].inject([]) do |h, (format, direction, arraycoder)|
159
+ h[format] ||= {}
160
+ h[format][direction] = CoderMap.new result, CODERS_BY_NAME[format][direction], format, arraycoder
161
+ h
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveRecord
2
+ class MigrationWithoutTransaction < Migration
3
+ end
4
+ end
@@ -0,0 +1,34 @@
1
+ module ActiveRecord
2
+ class Migrator
3
+ cattr_accessor :current_migration_for_transaction_test
4
+
5
+ ActiveRecord::Base.connection.instance_eval do
6
+ alias :old_supports_ddl_transactions? :supports_ddl_transactions?
7
+
8
+ def supports_ddl_transactions?
9
+ begin
10
+ require File.expand_path(ActiveRecord::Migrator.current_migration_for_transaction_test.filename)
11
+
12
+ if MigrationWithoutTransaction.in?(ActiveRecord::Migrator.current_migration_for_transaction_test.name.constantize.ancestors)
13
+ false
14
+ else
15
+ old_supports_ddl_transactions?
16
+ end
17
+ rescue
18
+ old_supports_ddl_transactions?
19
+ end
20
+ end
21
+ end
22
+
23
+ alias_method :old_migrate, :migrate
24
+
25
+ def migrate(&block)
26
+ ActiveRecord::Base.connection.raw_connection.type_map_for_results = PG::TypeMapAllStrings.new
27
+ ActiveRecord::Base.connection.raw_connection.type_map_for_queries = PG::TypeMapAllStrings.new
28
+
29
+ old_migrate do |migration|
30
+ (block.nil? ? true : block.call) && !(ActiveRecord::Migrator.current_migration_for_transaction_test = migration).nil?
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails/generators'
2
+
3
+ module Rails
4
+ module Generators
5
+ class <<self
6
+ alias_method :original_invoke, :invoke
7
+ end
8
+
9
+ def self.invoke(namespace, args=ARGV, config={})
10
+ original_invoke namespace.tr('-', '_'), args, config
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ version: false
2
+ compound: false
3
+ show-links: false
4
+ show-null: true
5
+ type-restriction: true
6
+ attribute-restriction: false
7
+ empty-is-null: true
8
+ page-size: 0
9
+ request-company-schema: false
10
+ request-sharded-schema: false
11
+ request-accounting-schema: false
12
+ request-accounting-prefix: false
13
+ pg-order-by: "created_at"
14
+ pg-search_path: '"$user", request-sharded-schema, public'
@@ -0,0 +1,15 @@
1
+ pt:
2
+ sp-duh:
3
+ exceptions:
4
+ jsonapi:
5
+ service_setup_error: 'O serviço JSONAPI não se encontra disponível porque os recursos não estão devidamente instalados.'
6
+ service_protocol_error: 'O protocolo definido para acesso ao serviço JSONAPI (%{protocol}) não é suportado. Os protocolos suportados são: %{protocols}.'
7
+ invalid_resource_configuration_error: 'A configuração de recursos definida no ficheiro %{file} é inválida.'
8
+ duplicate_resource_error: 'Tentativa de redefinção do recurso %{name}. O recurso já foi definido anteriormente.'
9
+ save_configuration_error: 'Erro ao gravar a configuração da JSONAPI na base de dados.'
10
+ invalid_resource_publisher_error: 'O módulo ou classe %{publisher} não é uma fonte de recursos JSONAPI válida.'
11
+ invalid_jsonapi_key_error: 'A chave %{key} não é válida para configurar a JSONAPI.'
12
+ sharding:
13
+ invalid_sharder_type_error: 'Erro de definição do particionamento para a partição %{namespace}: o tipo de partição pretendido, %{sharder_type}, não se encontra instalado.'
14
+ invalid_sharding_definition_error: 'Erro de definição do particionamento para a partição %{namespace}: não é possível aceder à estrutura de particionamento definida (%{shard_value_field} na estrutura %{shard_table} pelo id %{shard_id_field}).'
15
+ shard_not_found_error: 'Não existe a partição com o identificador %{shard_id} na estrutura %{shard_table} da partição %{namespace}.'
@@ -0,0 +1,10 @@
1
+ require 'rails/generators/active_record/migration/migration_generator'
2
+
3
+ class AccountingMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ # def create_migration_file
7
+ # set_local_assigns!
8
+ # migration_template "migration.rb", "db/migrate/#{file_name}.rb"
9
+ # end
10
+ end
@@ -0,0 +1,42 @@
1
+ class <%= migration_class_name %> < ActiveRecord::MigrationWithoutTransaction
2
+ def up
3
+ schema = 'accounting'
4
+ ['base_', 'small_', 'micro_', 'independent_', 'nonprofit_'].each do |table_prefix|
5
+ # Code to run on "accounting" schema
6
+
7
+ end
8
+
9
+ migrate_user_templates do |schema, table_prefix, ut|
10
+ # Code to run on user templates' schemas
11
+
12
+ # IF CHANGING TABLE we need to keep low cpu usage on DB
13
+ sleep 0.050
14
+ end
15
+
16
+ migrate_fiscal_years do |schema, table_prefix, fy|
17
+ # Code to run on fiscal years' schemas
18
+
19
+ # IF CHANGING TABLE we need to keep low cpu usage on DB
20
+ sleep 0.050
21
+ end
22
+ end
23
+
24
+ def down
25
+ schema = 'accounting'
26
+ ['base_', 'small_', 'micro_', 'independent_', 'nonprofit_'].each do |table_prefix|
27
+ # Code to run on "accounting" schema
28
+
29
+ end
30
+
31
+ rollback_user_templates do |schema, table_prefix, ut|
32
+ # Code to run on user templates' schemas
33
+
34
+ end
35
+
36
+ rollback_fiscal_years do |schema, table_prefix, fy|
37
+ # Code to run on fiscal years' schemas
38
+
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,10 @@
1
+ require 'rails/generators/active_record/migration/migration_generator'
2
+
3
+ class AccountingPayrollMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ # def create_migration_file
7
+ # set_local_assigns!
8
+ # migration_template "migration.rb", "db/migrate/#{file_name}.rb"
9
+ # end
10
+ end
@@ -0,0 +1,73 @@
1
+ class <%= migration_class_name %> < ActiveRecord::MigrationWithoutTransaction
2
+ def up
3
+ migrate_fiscal_years do |schema, table_prefix, fy, company_id|
4
+ result = execute %Q[ SELECT sharded_schema FROM sharding.get_sharded_schema_name(#{company_id}); ]
5
+ sharded_schema = result.first["sharded_schema"]
6
+ execute <<-SQL
7
+ DO $BODY$
8
+ DECLARE
9
+ BEGIN
10
+
11
+ WITH _needs_update AS (
12
+ SELECT tcda.id,
13
+ accounting.get_account_best_match('#{schema}','#{table_prefix}',COALESCE(tcda.social_organ_account::text,po.social_organ_account,pi.social_organ_account)) AS social_organ_account,
14
+ accounting.get_account_best_match('#{schema}','#{table_prefix}',COALESCE(tcda.employee_account::text,po.employee_account,pi.employee_account)) AS employee_account
15
+ FROM accounting.transaction_suggestions_categories tc
16
+ JOIN public.payroll_items pi ON pi.type = tc.id
17
+ LEFT JOIN public.payroll_item_overrides po ON (po.company_id = #{company_id} AND po.payroll_item_id = pi.id)
18
+ JOIN #{schema}.#{table_prefix}transaction_suggestions_default_accounts tcda ON (tcda.category_id = pi.type AND tcda.item_id = pi.id)
19
+ WHERE ( pi.company_id = #{company_id} OR pi.company_id IS NULL )
20
+ AND (tcda.social_organ_account IS NULL OR tcda.employee_account IS NULL)
21
+ )
22
+ UPDATE #{schema}.#{table_prefix}transaction_suggestions_default_accounts
23
+ SET social_organ_account = _needs_update.social_organ_account,
24
+ employee_account = _needs_update.employee_account
25
+ FROM _needs_update
26
+ WHERE #{schema}.#{table_prefix}transaction_suggestions_default_accounts.id = _needs_update.id
27
+ AND (_needs_update.social_organ_account IS NOT NULL OR _needs_update.employee_account IS NOT NULL);
28
+
29
+ INSERT INTO #{schema}.#{table_prefix}transaction_suggestions_default_accounts
30
+ (category_id, item_id, social_organ_account, employee_account, use_employee_account)
31
+ SELECT pi.type AS category_id,
32
+ pi.id AS item_id,
33
+ accounting.get_account_best_match('#{schema}','#{table_prefix}',COALESCE(po.social_organ_account,pi.social_organ_account)) AS social_organ_account,
34
+ accounting.get_account_best_match('#{schema}','#{table_prefix}',COALESCE(po.employee_account,pi.employee_account)) AS employee_account,
35
+ COALESCE(po.use_employee_account,pi.use_employee_account) AS use_employee_account
36
+ FROM accounting.transaction_suggestions_categories tc
37
+ JOIN public.payroll_items pi ON pi.type = tc.id
38
+ LEFT JOIN public.payroll_item_overrides po ON (po.company_id = #{company_id} AND po.payroll_item_id = pi.id)
39
+ LEFT JOIN #{schema}.#{table_prefix}transaction_suggestions_default_accounts tcda ON (tcda.category_id = pi.type AND tcda.item_id = pi.id)
40
+ WHERE ( pi.company_id = #{company_id} OR pi.company_id IS NULL )
41
+ AND tcda IS NULL
42
+ ORDER BY pi.id;
43
+
44
+ INSERT INTO #{schema}.#{table_prefix}transaction_suggestions_default_accounts
45
+ (category_id, item_id, social_organ_account, employee_account, use_employee_account)
46
+ SELECT CASE
47
+ WHEN paa.category = 'Taxes' THEN 'Payroll::Tax'
48
+ WHEN paa.category = 'Third parties' THEN 'Payroll::ThirdParty'
49
+ END AS category_id,
50
+ paa.id AS item_id,
51
+ accounting.get_account_best_match('#{schema}','#{table_prefix}',paa.social_organ_account) AS social_organ_account,
52
+ accounting.get_account_best_match('#{schema}','#{table_prefix}',paa.employee_account) AS employee_account,
53
+ paa.use_employee_account
54
+ FROM #{sharded_schema}.payroll_accounting_accounts paa
55
+ LEFT JOIN #{schema}.#{table_prefix}transaction_suggestions_default_accounts tcda ON (tcda.category_id IN ('Payroll::Tax','Payroll::ThirdParty') AND tcda.item_id = paa.id)
56
+ WHERE paa.company_id = #{company_id}
57
+ AND paa.category IN ('Taxes', 'Third parties')
58
+ AND paa.code NOT IN ('BBNK','BCSH')
59
+ AND tcda IS NULL
60
+ ORDER BY paa.id;
61
+ END;
62
+ $BODY$ LANGUAGE 'plpgsql';
63
+ SQL
64
+ end
65
+ end
66
+
67
+ def down
68
+ puts "Not reverting"
69
+ rollback_fiscal_years {}
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,10 @@
1
+ require 'rails/generators/active_record/migration/migration_generator'
2
+
3
+ class ShardedMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ # def create_migration_file
7
+ # set_local_assigns!
8
+ # migration_template "migration.rb", "db/migrate/#{file_name}.rb"
9
+ # end
10
+ end
@@ -0,0 +1,45 @@
1
+ class <%= migration_class_name %> < ActiveRecord::MigrationWithoutTransaction
2
+ def up
3
+ migrate_companies do |schema_name, company_id|
4
+ case schema_name
5
+ when 'public'
6
+ # Code to run on "public" schema
7
+
8
+ when 'sharded'
9
+ # Code to run on "sharded" schema
10
+ # STUCTURE CHANGES TO TABLES IN THIS SCHEMA MUST ONLY RUN IF ADDING OR REMOVING COLUMNS, NOTHING ELSE!
11
+
12
+ else
13
+ # Code to run on sharded companies' schemas
14
+
15
+ end
16
+ # IF CHANGING TABLE we need to keep low cpu usage on DB
17
+ sleep 0.100
18
+ end
19
+
20
+ # If migration add structural changes on public objects and want run migration
21
+ # withou a full deploy, please uncomment the next line
22
+ # invalidate_postgresql_redis_cache!
23
+ end
24
+
25
+ def down
26
+ rollback_companies do |schema_name, company_id|
27
+ case schema_name
28
+ when 'public'
29
+ # Code to run on "public" schema
30
+
31
+ when 'sharded'
32
+ # Code to run on "sharded" schema
33
+ # STUCTURE CHANGES TO TABLES IN THIS SCHEMA MUST ONLY RUN IF ADDING OR REMOVING COLUMNS, NOTHING ELSE!
34
+
35
+ else
36
+ # Code to run on sharded companies' schemas
37
+
38
+ end
39
+ end
40
+
41
+ # If migration add structural changes on public objects and want run migration
42
+ # withou a full deploy, please uncomment the next line
43
+ # invalidate_postgresql_redis_cache!
44
+ end
45
+ end