pg_trunk 0.1.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 (196) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +87 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +4 -0
  5. data/.rubocop.yml +92 -0
  6. data/.yardopts +4 -0
  7. data/CHANGELOG.md +31 -0
  8. data/CONTRIBUTING.md +17 -0
  9. data/Gemfile +22 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +141 -0
  12. data/Rakefile +16 -0
  13. data/bin/console +8 -0
  14. data/bin/rake +19 -0
  15. data/bin/rspec +19 -0
  16. data/bin/setup +8 -0
  17. data/bin/yard +19 -0
  18. data/lib/pg_trunk/core/adapters/postgres.rb +80 -0
  19. data/lib/pg_trunk/core/dependencies_resolver.rb +101 -0
  20. data/lib/pg_trunk/core/generators.rb +140 -0
  21. data/lib/pg_trunk/core/operation/attributes.rb +78 -0
  22. data/lib/pg_trunk/core/operation/callbacks.rb +40 -0
  23. data/lib/pg_trunk/core/operation/generators.rb +51 -0
  24. data/lib/pg_trunk/core/operation/inversion.rb +70 -0
  25. data/lib/pg_trunk/core/operation/registration.rb +55 -0
  26. data/lib/pg_trunk/core/operation/ruby_builder.rb +112 -0
  27. data/lib/pg_trunk/core/operation/ruby_helpers.rb +99 -0
  28. data/lib/pg_trunk/core/operation/sql_helpers.rb +44 -0
  29. data/lib/pg_trunk/core/operation/validations.rb +21 -0
  30. data/lib/pg_trunk/core/operation.rb +78 -0
  31. data/lib/pg_trunk/core/qualified_name.rb +165 -0
  32. data/lib/pg_trunk/core/railtie/command_recorder.rb +30 -0
  33. data/lib/pg_trunk/core/railtie/custom_types.rb +37 -0
  34. data/lib/pg_trunk/core/railtie/migration.rb +50 -0
  35. data/lib/pg_trunk/core/railtie/migrator.rb +22 -0
  36. data/lib/pg_trunk/core/railtie/schema_dumper.rb +75 -0
  37. data/lib/pg_trunk/core/railtie/schema_migration.rb +22 -0
  38. data/lib/pg_trunk/core/railtie/statements.rb +21 -0
  39. data/lib/pg_trunk/core/railtie.rb +35 -0
  40. data/lib/pg_trunk/core/registry.rb +159 -0
  41. data/lib/pg_trunk/core/serializers/array_of_hashes_serializer.rb +28 -0
  42. data/lib/pg_trunk/core/serializers/array_of_strings_serializer.rb +29 -0
  43. data/lib/pg_trunk/core/serializers/array_of_symbols_serializer.rb +28 -0
  44. data/lib/pg_trunk/core/serializers/array_serializer.rb +22 -0
  45. data/lib/pg_trunk/core/serializers/lowercase_string_serializer.rb +21 -0
  46. data/lib/pg_trunk/core/serializers/multiline_text_serializer.rb +21 -0
  47. data/lib/pg_trunk/core/serializers/qualified_name_serializer.rb +27 -0
  48. data/lib/pg_trunk/core/serializers/symbol_serializer.rb +22 -0
  49. data/lib/pg_trunk/core/serializers.rb +16 -0
  50. data/lib/pg_trunk/core/validators/all_items_valid_validator.rb +15 -0
  51. data/lib/pg_trunk/core/validators/difference_validator.rb +19 -0
  52. data/lib/pg_trunk/core/validators.rb +10 -0
  53. data/lib/pg_trunk/core.rb +21 -0
  54. data/lib/pg_trunk/generators.rb +7 -0
  55. data/lib/pg_trunk/operations/check_constraints/add_check_constraint.rb +109 -0
  56. data/lib/pg_trunk/operations/check_constraints/base.rb +69 -0
  57. data/lib/pg_trunk/operations/check_constraints/drop_check_constraint.rb +60 -0
  58. data/lib/pg_trunk/operations/check_constraints/rename_check_constraint.rb +54 -0
  59. data/lib/pg_trunk/operations/check_constraints/validate_check_constraint.rb +39 -0
  60. data/lib/pg_trunk/operations/check_constraints.rb +14 -0
  61. data/lib/pg_trunk/operations/composite_types/base.rb +61 -0
  62. data/lib/pg_trunk/operations/composite_types/change_composite_type.rb +136 -0
  63. data/lib/pg_trunk/operations/composite_types/column.rb +118 -0
  64. data/lib/pg_trunk/operations/composite_types/create_composite_type.rb +99 -0
  65. data/lib/pg_trunk/operations/composite_types/drop_composite_type.rb +67 -0
  66. data/lib/pg_trunk/operations/composite_types/rename_composite_type.rb +44 -0
  67. data/lib/pg_trunk/operations/composite_types.rb +15 -0
  68. data/lib/pg_trunk/operations/domains/base.rb +46 -0
  69. data/lib/pg_trunk/operations/domains/change_domain.rb +140 -0
  70. data/lib/pg_trunk/operations/domains/constraint.rb +93 -0
  71. data/lib/pg_trunk/operations/domains/create_domain.rb +124 -0
  72. data/lib/pg_trunk/operations/domains/drop_domain.rb +65 -0
  73. data/lib/pg_trunk/operations/domains/rename_domain.rb +44 -0
  74. data/lib/pg_trunk/operations/domains.rb +15 -0
  75. data/lib/pg_trunk/operations/enums/base.rb +47 -0
  76. data/lib/pg_trunk/operations/enums/change.rb +55 -0
  77. data/lib/pg_trunk/operations/enums/change_enum.rb +119 -0
  78. data/lib/pg_trunk/operations/enums/create_enum.rb +83 -0
  79. data/lib/pg_trunk/operations/enums/drop_enum.rb +63 -0
  80. data/lib/pg_trunk/operations/enums/rename_enum.rb +44 -0
  81. data/lib/pg_trunk/operations/enums.rb +15 -0
  82. data/lib/pg_trunk/operations/foreign_keys/add_foreign_key.rb +174 -0
  83. data/lib/pg_trunk/operations/foreign_keys/base.rb +155 -0
  84. data/lib/pg_trunk/operations/foreign_keys/drop_foreign_key.rb +76 -0
  85. data/lib/pg_trunk/operations/foreign_keys/rename_foreign_key.rb +63 -0
  86. data/lib/pg_trunk/operations/foreign_keys.rb +16 -0
  87. data/lib/pg_trunk/operations/functions/base.rb +54 -0
  88. data/lib/pg_trunk/operations/functions/change_function.rb +108 -0
  89. data/lib/pg_trunk/operations/functions/create_function.rb +198 -0
  90. data/lib/pg_trunk/operations/functions/drop_function.rb +88 -0
  91. data/lib/pg_trunk/operations/functions/rename_function.rb +57 -0
  92. data/lib/pg_trunk/operations/functions.rb +14 -0
  93. data/lib/pg_trunk/operations/indexes/add_index.rb +68 -0
  94. data/lib/pg_trunk/operations/indexes.rb +10 -0
  95. data/lib/pg_trunk/operations/materialized_views/base.rb +79 -0
  96. data/lib/pg_trunk/operations/materialized_views/change_materialized_view.rb +139 -0
  97. data/lib/pg_trunk/operations/materialized_views/column.rb +94 -0
  98. data/lib/pg_trunk/operations/materialized_views/create_materialized_view.rb +170 -0
  99. data/lib/pg_trunk/operations/materialized_views/drop_materialized_view.rb +70 -0
  100. data/lib/pg_trunk/operations/materialized_views/refresh_materialized_view.rb +48 -0
  101. data/lib/pg_trunk/operations/materialized_views/rename_materialized_view.rb +61 -0
  102. data/lib/pg_trunk/operations/materialized_views.rb +17 -0
  103. data/lib/pg_trunk/operations/procedures/base.rb +42 -0
  104. data/lib/pg_trunk/operations/procedures/change_procedure.rb +107 -0
  105. data/lib/pg_trunk/operations/procedures/create_procedure.rb +146 -0
  106. data/lib/pg_trunk/operations/procedures/drop_procedure.rb +66 -0
  107. data/lib/pg_trunk/operations/procedures/rename_procedure.rb +57 -0
  108. data/lib/pg_trunk/operations/procedures.rb +14 -0
  109. data/lib/pg_trunk/operations/statistics/base.rb +94 -0
  110. data/lib/pg_trunk/operations/statistics/create_statistics.rb +181 -0
  111. data/lib/pg_trunk/operations/statistics/drop_statistics.rb +75 -0
  112. data/lib/pg_trunk/operations/statistics/rename_statistics.rb +48 -0
  113. data/lib/pg_trunk/operations/statistics.rb +13 -0
  114. data/lib/pg_trunk/operations/tables/create_table.rb +75 -0
  115. data/lib/pg_trunk/operations/tables.rb +10 -0
  116. data/lib/pg_trunk/operations/triggers/base.rb +119 -0
  117. data/lib/pg_trunk/operations/triggers/change_trigger.rb +82 -0
  118. data/lib/pg_trunk/operations/triggers/create_trigger.rb +208 -0
  119. data/lib/pg_trunk/operations/triggers/drop_trigger.rb +66 -0
  120. data/lib/pg_trunk/operations/triggers/rename_trigger.rb +71 -0
  121. data/lib/pg_trunk/operations/triggers.rb +14 -0
  122. data/lib/pg_trunk/operations/views/base.rb +38 -0
  123. data/lib/pg_trunk/operations/views/change_view.rb +90 -0
  124. data/lib/pg_trunk/operations/views/create_view.rb +115 -0
  125. data/lib/pg_trunk/operations/views/drop_view.rb +69 -0
  126. data/lib/pg_trunk/operations/views/rename_view.rb +58 -0
  127. data/lib/pg_trunk/operations/views.rb +14 -0
  128. data/lib/pg_trunk/operations.rb +23 -0
  129. data/lib/pg_trunk/version.rb +6 -0
  130. data/lib/pg_trunk.rb +27 -0
  131. data/pg_trunk.gemspec +34 -0
  132. data/spec/dummy/.gitignore +16 -0
  133. data/spec/dummy/Rakefile +15 -0
  134. data/spec/dummy/bin/bundle +6 -0
  135. data/spec/dummy/bin/rails +6 -0
  136. data/spec/dummy/bin/rake +6 -0
  137. data/spec/dummy/config/application.rb +18 -0
  138. data/spec/dummy/config/boot.rb +7 -0
  139. data/spec/dummy/config/database.yml +14 -0
  140. data/spec/dummy/config/environment.rb +7 -0
  141. data/spec/dummy/config.ru +6 -0
  142. data/spec/dummy/db/materialized_views/admin_users_v01.sql +1 -0
  143. data/spec/dummy/db/migrate/.keep +0 -0
  144. data/spec/dummy/db/schema.rb +18 -0
  145. data/spec/dummy/db/views/admin_users_v01.sql +1 -0
  146. data/spec/dummy/db/views/admin_users_v02.sql +1 -0
  147. data/spec/operations/check_constraints/add_check_constraint_spec.rb +85 -0
  148. data/spec/operations/check_constraints/drop_check_constraint_spec.rb +111 -0
  149. data/spec/operations/check_constraints/rename_check_constraint_spec.rb +90 -0
  150. data/spec/operations/composite_types/change_composite_type_spec.rb +257 -0
  151. data/spec/operations/composite_types/create_composite_type_spec.rb +55 -0
  152. data/spec/operations/composite_types/drop_composite_type_spec.rb +109 -0
  153. data/spec/operations/composite_types/rename_composite_type_spec.rb +74 -0
  154. data/spec/operations/dependency_resolver_spec.rb +177 -0
  155. data/spec/operations/domains/change_domain_spec.rb +287 -0
  156. data/spec/operations/domains/create_domain_spec.rb +69 -0
  157. data/spec/operations/domains/drop_domain_spec.rb +119 -0
  158. data/spec/operations/domains/rename_domain_spec.rb +70 -0
  159. data/spec/operations/enums/change_enum_spec.rb +157 -0
  160. data/spec/operations/enums/create_enum_spec.rb +40 -0
  161. data/spec/operations/enums/drop_enum_spec.rb +120 -0
  162. data/spec/operations/enums/rename_enum_spec.rb +72 -0
  163. data/spec/operations/foreign_keys/add_foreign_key_spec.rb +208 -0
  164. data/spec/operations/foreign_keys/drop_foreign_key_spec.rb +167 -0
  165. data/spec/operations/foreign_keys/rename_foreign_key_spec.rb +101 -0
  166. data/spec/operations/functions/change_function_spec.rb +166 -0
  167. data/spec/operations/functions/create_function_spec.rb +192 -0
  168. data/spec/operations/functions/drop_function_spec.rb +182 -0
  169. data/spec/operations/functions/rename_function_spec.rb +101 -0
  170. data/spec/operations/indexes/add_index_spec.rb +94 -0
  171. data/spec/operations/materialized_views/change_materialized_view_spec.rb +190 -0
  172. data/spec/operations/materialized_views/create_materialized_view_spec.rb +144 -0
  173. data/spec/operations/materialized_views/drop_materialized_view_spec.rb +145 -0
  174. data/spec/operations/materialized_views/refresh_materialized_view_spec.rb +79 -0
  175. data/spec/operations/materialized_views/rename_materialized_view_spec.rb +88 -0
  176. data/spec/operations/procedures/change_procedure_spec.rb +175 -0
  177. data/spec/operations/procedures/create_procedure_spec.rb +151 -0
  178. data/spec/operations/procedures/drop_procedure_spec.rb +159 -0
  179. data/spec/operations/procedures/rename_procedure_spec.rb +107 -0
  180. data/spec/operations/statistics/create_statistics_spec.rb +230 -0
  181. data/spec/operations/statistics/drop_statistics_spec.rb +106 -0
  182. data/spec/operations/statistics/rename_statistics_spec.rb +129 -0
  183. data/spec/operations/tables/create_table_spec.rb +53 -0
  184. data/spec/operations/tables/rename_table_spec.rb +37 -0
  185. data/spec/operations/triggers/change_trigger_spec.rb +195 -0
  186. data/spec/operations/triggers/create_trigger_spec.rb +104 -0
  187. data/spec/operations/triggers/drop_trigger_spec.rb +124 -0
  188. data/spec/operations/triggers/rename_trigger_spec.rb +160 -0
  189. data/spec/operations/views/change_view_spec.rb +144 -0
  190. data/spec/operations/views/create_view_spec.rb +134 -0
  191. data/spec/operations/views/drop_view_spec.rb +146 -0
  192. data/spec/operations/views/rename_view_spec.rb +85 -0
  193. data/spec/pg_trunk/dependencies_resolver_spec.rb +43 -0
  194. data/spec/spec_helper.rb +28 -0
  195. data/spec/support/migrations_helper.rb +376 -0
  196. metadata +348 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 98c9050bc62e8f9a33f87ff77a836189fca018a968ff1fd487f1e5b613b1278f
4
+ data.tar.gz: 30bcc2a1d61cc3343a95e752d8307c20b1326b57969ac0479a3e4ef161026747
5
+ SHA512:
6
+ metadata.gz: a4ba64e08cb9a12ce958e1a4a13a88370e4a20e8fe25cf9da19731c5e77ea8d952decabaebd89c6c0af545f34e955f274a768ad28282345e0365ef57f314d69b
7
+ data.tar.gz: 62289de65886d00d28a979149909839f237afdd9e1144f61710306f4da4258e9487da36e07ef21f46e90b86f63cd6b18a17db59317728eac56ce37524cdbc60a
@@ -0,0 +1,87 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ branches:
9
+ - "*"
10
+
11
+ jobs:
12
+ build:
13
+ name: Ruby ${{ matrix.ruby }}, Rails ${{ matrix.rails }}, PostgreSQL ${{ matrix.postgres }}
14
+
15
+ strategy:
16
+ fail-fast: true
17
+ matrix:
18
+ ruby:
19
+ - "3.0"
20
+ rails:
21
+ - "7.0"
22
+ postgres:
23
+ - 10
24
+ - 11
25
+ - 12
26
+ - 13
27
+ - 14
28
+ include: # for backward-compatibility
29
+ - ruby: "2.7"
30
+ rails: "5.2"
31
+ postgres: 10
32
+ - ruby: "3.0"
33
+ rails: "6.1"
34
+ postgres: 10
35
+
36
+ runs-on: ubuntu-latest
37
+
38
+ services:
39
+ postgres:
40
+ image: postgres:${{ matrix.postgres }}
41
+ env:
42
+ POSTGRES_USER: postgres
43
+ POSTGRES_PASSWORD: postgres
44
+ ports:
45
+ - 5432:5432
46
+ options: >-
47
+ --health-cmd pg_isready
48
+ --health-interval 10s
49
+ --health-timeout 5s
50
+ --health-retries 5
51
+
52
+ env:
53
+ RAILS_VERSION: ${{ matrix.rails }}
54
+ POSTGRES_USER: "postgres"
55
+ POSTGRES_PASSWORD: "postgres"
56
+
57
+ steps:
58
+ - name: Checkout
59
+ uses: actions/checkout@v2
60
+
61
+ - name: Install Ruby ${{ matrix.ruby }}
62
+ uses: ruby/setup-ruby@v1.61.1
63
+ with:
64
+ ruby-version: ${{ matrix.ruby }}
65
+
66
+ - name: Install dependent libraries
67
+ run: sudo apt-get install libpq-dev
68
+
69
+ - name: Generate lockfile
70
+ run: bundle lock
71
+
72
+ - name: Cache dependencies
73
+ uses: actions/cache@v1
74
+ with:
75
+ path: vendor/bundle
76
+ key: bundle-${{ hashFiles('Gemfile.lock') }}
77
+
78
+ - name: Set up PGTrunk
79
+ run: bin/setup
80
+
81
+ - name: Check code style
82
+ run: bundle exec rubocop
83
+ continue-on-error: false
84
+
85
+ - name: Run tests
86
+ run: bundle exec rake --trace
87
+ continue-on-error: false
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /gemfiles/*.gemfile.lock
7
+ /Gemfile.lock
8
+ /tmp/
9
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --require spec_helper
3
+ --order random
4
+ --warning
data/.rubocop.yml ADDED
@@ -0,0 +1,92 @@
1
+ ---
2
+ AllCops:
3
+ NewCops: enable
4
+ TargetRubyVersion: 2.7
5
+
6
+ Lint/AmbiguousBlockAssociation:
7
+ IgnoredMethods:
8
+ - change
9
+
10
+ # Enable long'n'complex methods in operations
11
+ # because we made those definitions using a DSL
12
+ # which 'regularizes' a code, so we can afford that complexity.
13
+
14
+ Metrics/BlockLength:
15
+ # these methods should wrap a lot of definitions by design
16
+ IgnoredMethods:
17
+ - class_methods
18
+ - configure
19
+ - context
20
+ - describe
21
+ - define
22
+ Exclude:
23
+ - lib/pg_trunk/operations/**/*.rb
24
+
25
+ Metrics/AbcSize:
26
+ Exclude:
27
+ - lib/pg_trunk/operations/**/*.rb
28
+
29
+ Metrics/ClassLength:
30
+ Exclude:
31
+ - spec/**/*_spec.rb
32
+ - lib/pg_trunk/operations/**/*.rb
33
+
34
+ Metrics/CyclomaticComplexity:
35
+ Exclude:
36
+ - lib/pg_trunk/operations/**/*.rb
37
+
38
+ Metrics/MethodLength:
39
+ Exclude:
40
+ - lib/pg_trunk/operations/**/*.rb
41
+
42
+ Metrics/PerceivedComplexity:
43
+ Exclude:
44
+ - lib/pg_trunk/operations/**/*.rb
45
+
46
+ # Enable long modules in specs
47
+ Metrics/ModuleLength:
48
+ Exclude:
49
+ - spec/**/*_spec.rb
50
+
51
+ # Start class definitions from inline
52
+ # private def initialize(...)
53
+ Style/AccessModifierDeclarations:
54
+ Enabled: false
55
+
56
+ # Prefer the following style:
57
+ #
58
+ # module Foo:Bar # directly accessible from Baz
59
+ # class Baz
60
+ # # ...
61
+ Style/ClassAndModuleChildren:
62
+ Enabled: false
63
+
64
+ # The convention is too opinionated
65
+ Style/DocumentDynamicEvalDefinition:
66
+ Enabled: false
67
+
68
+ # The convention is too opinionated
69
+ Style/EmptyCaseCondition:
70
+ Enabled: false
71
+
72
+ Style/EmptyMethod:
73
+ EnforcedStyle: compact
74
+
75
+ Style/ModuleFunction:
76
+ EnforcedStyle: extend_self
77
+
78
+ Style/StringLiterals:
79
+ EnforcedStyle: double_quotes
80
+
81
+ Style/TrailingCommaInArguments:
82
+ EnforcedStyleForMultiline: consistent_comma
83
+
84
+ Style/TrailingCommaInArrayLiteral:
85
+ EnforcedStyleForMultiline: consistent_comma
86
+
87
+ Style/TrailingCommaInHashLiteral:
88
+ EnforcedStyleForMultiline: consistent_comma
89
+
90
+ Style/WordArray:
91
+ Exclude:
92
+ - spec/features/**/*
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ --hide-api private
2
+ --exclude templates
3
+ --markup markdown
4
+ --markup-provider redcarpet
data/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ The noteworthy changes for each PGTrunk version are included here.
4
+ The format is based on [Keep a Changelog] and this project adheres to [Semantic Versioning].
5
+ For a complete changelog, see the [commits] for each version via the version links.
6
+
7
+ ## [0.1.0] (2022-01-14)
8
+
9
+ This is a first public release (nepalez)
10
+
11
+ Supported features:
12
+
13
+ - tables
14
+ - indexes (separated from tables)
15
+ - check constraints (separated from tables)
16
+ - foreign keys (including multi-column ones)
17
+ - views
18
+ - materialized views
19
+ - functions
20
+ - procedures
21
+ - triggers
22
+ - custom statistics
23
+ - enumerable types
24
+ - composite types
25
+ - domains types
26
+
27
+ [0.1.0]: https://github.com/nepalez/pg_trunk/releases/tag/v0.1.0
28
+
29
+ [Keep a Changelog]: http://keepachangelog.com/
30
+ [Semantic Versioning]: http://semver.org/
31
+ [commits]: https://github.com/nepalez/pg_trunk/commits/master
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,17 @@
1
+ # Contributing
2
+
3
+ 1. Fork the repository.
4
+ 2. Run `bin/setup`, which will install dependencies and create the dummy
5
+ application database.
6
+ 3. Run `rake` to verify that the tests pass against the version of Rails you are
7
+ running locally, and that the code is styled properly.
8
+ 4. Make your change with new passing tests, following the existing style.
9
+ 5. Write a [good commit message], push your fork, and submit a pull request.
10
+ 6. CI will run the test suite on all configured versions of Ruby and Rails.
11
+ Address any failures.
12
+
13
+ [good commit message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
14
+
15
+ Others will give constructive feedback. This is a time for discussion and
16
+ improvements, and making the necessary changes will be required before we can
17
+ merge the contribution.
data/Gemfile ADDED
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in pg_trunk.gemspec
6
+ gemspec
7
+
8
+ gem "appraisal", "~> 2.3.0"
9
+ gem "bundler", ">= 1.5"
10
+ gem "database_cleaner"
11
+ gem "pg"
12
+ gem "pry"
13
+ gem "pry-byebug"
14
+ gem "rake"
15
+ gem "redcarpet"
16
+ gem "rspec", ">= 3.3"
17
+ gem "rspec-its"
18
+ gem "rubocop"
19
+ gem "rubocop-rake"
20
+ gem "rubocop-rspec"
21
+ gem "test-prof"
22
+ gem "yard"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Andrew Kozin (nepalez)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # PGTrunk
2
+
3
+ Empower PostgreSQL migrations in Rails app
4
+
5
+ <a href="https://evilmartians.com/">
6
+ <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
7
+
8
+ [![Gem Version][gem-badger]][gem]
9
+ [![Build Status][build-badger]][build]
10
+
11
+ PGTrunk adds methods to `ActiveRecord::Migration` to create and manage
12
+ various PostgreSQL objects (like views, functions, triggers, statistics, types etc.)
13
+ in Rails.
14
+
15
+ This gem is greatly influenced by the [Scenic], [F(x)] and [ActiveRecord::PostgtresEnum] projects
16
+ but takes some steps further.
17
+
18
+ In addition to support of different objects, we are solving a problem of interdependency between them.
19
+ For example, you can create a table, then a function using its type as an argument,
20
+ then check constraint and index using the function:
21
+
22
+ ```ruby
23
+ create_table "users" do |t|
24
+ t.text "first_name"
25
+ t.text "last_name"
26
+ end
27
+
28
+ # depends on the `users` table
29
+ create_function "full_name(u users) text" do |f|
30
+ f.volatility :immutable
31
+ f.strict true
32
+ f.parallel :safe
33
+ f.body <<~SQL.strip
34
+ string_trim(
35
+ SELECT COALESCE(u.first_name, '') + '.' + COALESCE(u.second_name, ''),
36
+ '.'
37
+ )
38
+ SQL
39
+ end
40
+
41
+ # both objects below depend on the `users` and `full_name(users)`
42
+ # so they couldn't be placed inside the `create_table` definition in the schema.
43
+
44
+ create_index "users", "full_name(users.*)", unique: true
45
+
46
+ # users.full_name is the PostgreSQL alternative syntax for the `full_name(users.*)`
47
+ create_check_constraint "users", "length(users.full_name) > 0", name: "full_name_present"
48
+ ```
49
+
50
+ Notice, that we had to separate definitions of indexes and check constraints from tables,
51
+ because there can be other objects (like functions or types) squeezing between them.
52
+
53
+ Another difference from aforementioned gems is that we explicitly register
54
+ all objects created by migrations in the special table (`pg_trunk`).
55
+ This let us distinct objects created by "regular" migration from temporary ones
56
+ added manually and exclude the latter from the schema. We bind any object
57
+ to a particular version of migration which added it. That's how only those
58
+ objects that belong to the current branch are dumped into the `schema.rb`.
59
+
60
+ As of today we support creation, modification and dropping the following objects:
61
+
62
+ - tables
63
+ - indexes
64
+ - foreign keys (including multi-column ones)
65
+ - check constraints
66
+ - views
67
+ - materialized views
68
+ - functions
69
+ - procedures
70
+ - triggers
71
+ - custom statistics
72
+ - enumerable types
73
+ - composite types
74
+ - domains types
75
+
76
+ For `tables` and `indexes` we reuse the ActiveRecord's native methods.
77
+ For `check constraints` and `foreign keys` we support both the native definitions inside the table
78
+ and standalone methods (like `create_foreign_key`) with additional features.
79
+ The other methods are implemented from scratch.
80
+
81
+ In the future other objects like aggregate functions, range types, operators, collations, and more
82
+ will be supported.
83
+
84
+ From now and on we support all versions of PostgreSQL since v10.
85
+
86
+ The gem is targeted to support PostgreSQL-specific features, that's why we won't provide adapters to other databases like [Scenic] does.
87
+
88
+ ## Documentation
89
+
90
+ The gem provides a lot of additional methods to create, rename, change a drop various objects.
91
+ You can find the necessary details in the gem's [wiki].
92
+
93
+ ## Installation
94
+
95
+ Add this line to your application's Gemfile:
96
+
97
+ ```ruby
98
+ gem 'pg_trunk'
99
+ ```
100
+
101
+ And then execute:
102
+
103
+ ```shell
104
+ $ bundle install
105
+ ```
106
+
107
+ Or install it yourself as:
108
+
109
+ ```shell
110
+ $ gem install pg_trunk
111
+ ```
112
+
113
+ Add the line somewhere in your ruby code:
114
+
115
+ ```ruby
116
+ require "pg_trunk"
117
+ ```
118
+
119
+ ## Development
120
+
121
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
122
+
123
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
124
+
125
+ ## Contributing
126
+
127
+ Bug reports and pull requests are welcome on GitHub at `https://github.com/nepalez/pg_trunk`.
128
+
129
+ ## License
130
+
131
+ The gem is available as open source under the terms of the [MIT License].
132
+
133
+ [build-badger]: https://github.com/nepalez/pg_trunk/workflows/CI/badge.svg
134
+ [build]: https://github.com/nepalez/pg_trunk/actions?query=workflow%3ACI+branch%3Amaster
135
+ [gem-badger]: https://img.shields.io/gem/v/pg_trunk.svg?style=flat
136
+ [gem]: https://rubygems.org/gems/pg_trunk
137
+ [MIT License]: https://opensource.org/licenses/MIT
138
+ [Scenic]: https://github.com/scenic-views/scenic
139
+ [F(x)]: https://github.com/teoljungberg/fx
140
+ [ActiveRecord::PostgtresEnum]: https://github.com/bibendi/activerecord-postgres_enum
141
+ [wiki]: https://github.com/nepalez/pg_trunk/wiki
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ namespace :dummy do
7
+ require_relative "spec/dummy/config/application"
8
+ Dummy::Application.load_tasks
9
+ end
10
+
11
+ task(:spec).clear
12
+ desc "Run specs"
13
+ RSpec::Core::RakeTask.new(:spec) { |task| task.verbose = false }
14
+
15
+ desc "Run the specs on the dummy database"
16
+ task default: %w[dummy:db:reset spec]
data/bin/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "pg_trunk"
6
+ require "pry"
7
+
8
+ Pry.start
data/bin/rake ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||=
13
+ File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath)
14
+
15
+ require "rubygems"
16
+ require "bundler/setup"
17
+
18
+ # noinspection RubyResolve
19
+ load Gem.bin_path("rake", "rake")
data/bin/rspec ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||=
13
+ File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath)
14
+
15
+ require "rubygems"
16
+ require "bundler/setup"
17
+
18
+ # noinspection RubyResolve
19
+ load Gem.bin_path("rspec-core", "rspec")
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/bin/yard ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'yard' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||=
13
+ File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath)
14
+
15
+ require "rubygems"
16
+ require "bundler/setup"
17
+
18
+ # noinspection RubyResolve
19
+ load Gem.bin_path("yard", "yard")
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PGTrunk
4
+ # @private
5
+ # PGTrunk database adapters.
6
+ #
7
+ # PGTrunk ships with a Postgres adapter only,
8
+ # with interface implemented as +PGTrunk::Adapters::Postgres+.
9
+ #
10
+ module Adapters
11
+ # Creates an instance of the PGTrunk Postgres adapter.
12
+ # This is the only supported adapter for PGTrunk.
13
+ #
14
+ # @param [#connection] connectable An object that returns the connection
15
+ # for PGTrunk to use. Defaults to `ActiveRecord::Base`.
16
+ #
17
+ class Postgres
18
+ # Decorates an ActiveRecord connection with methods that help determine
19
+ # the connections capabilities.
20
+ #
21
+ # Every attempt is made to use the versions of these methods defined by
22
+ # Rails where they are available and public before falling back to our own
23
+ # implementations for older Rails versions.
24
+ #
25
+ # @private
26
+ class Connection < SimpleDelegator
27
+ def server_version
28
+ raw_connection.server_version.to_s
29
+ end
30
+
31
+ # Expose private method helpers
32
+
33
+ def check_constraint_name(table, expression)
34
+ __getobj__.send(
35
+ :check_constraint_name,
36
+ table,
37
+ expression: expression,
38
+ )
39
+ end
40
+
41
+ def strip_table_name(table)
42
+ __getobj__.send(:strip_table_name_prefix_and_suffix, table)
43
+ end
44
+ end
45
+
46
+ # Execute operation by its definition
47
+ # @param [Class < PgExtra::Operation] operation
48
+ def execute_operation(operation)
49
+ query = operation.to_sql(server_version)
50
+ connection.execute(query) if query
51
+ end
52
+
53
+ def dumper
54
+ # This instance is used to dump the table
55
+ # using its name extracted from the database.
56
+ # That's why we can skip prefix/suffix definitions
57
+ # in the parameters of the constructor.
58
+ @dumper ||= connection.create_schema_dumper({})
59
+ end
60
+
61
+ private
62
+
63
+ attr_reader :connectable
64
+
65
+ def connection
66
+ @connection ||= Connection.new(ActiveRecord::Base.connection)
67
+ end
68
+
69
+ def respond_to_missing?(symbol, *)
70
+ connection.respond_to?(symbol, true)
71
+ end
72
+
73
+ def method_missing(symbol, *args, **opts, &block)
74
+ super unless connection.respond_to?(symbol, true)
75
+
76
+ connection.send(symbol, *args, **opts, &block)
77
+ end
78
+ end
79
+ end
80
+ end