fx 0.1.0 → 0.11.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 +5 -5
- data/.github/scripts/check-eol +95 -0
- data/.github/workflows/ci.yml +61 -0
- data/.github/workflows/eol-check.yml +30 -0
- data/.rspec +1 -1
- data/.standard.yml +3 -0
- data/CHANGELOG.md +186 -0
- data/CONTRIBUTING.md +13 -4
- data/Gemfile +21 -2
- data/LICENSE +18 -0
- data/README.md +99 -14
- data/Rakefile +11 -1
- data/bin/rake +2 -3
- data/bin/rspec +13 -3
- data/bin/setup +1 -4
- data/bin/standardrb +27 -0
- data/bin/yard +13 -3
- data/fx.gemspec +20 -27
- data/lib/fx/adapters/postgres/connection.rb +6 -0
- data/lib/fx/adapters/postgres/functions.rb +16 -28
- data/lib/fx/adapters/postgres/query_executor.rb +34 -0
- data/lib/fx/adapters/postgres/triggers.rb +14 -28
- data/lib/fx/adapters/postgres.rb +30 -17
- data/lib/fx/command_recorder.rb +104 -13
- data/lib/fx/configuration.rb +10 -25
- data/lib/fx/definition.rb +32 -10
- data/lib/fx/function.rb +23 -9
- data/lib/fx/railtie.rb +15 -0
- data/lib/fx/schema_dumper.rb +33 -10
- data/lib/fx/statements.rb +213 -11
- data/lib/fx/trigger.rb +5 -3
- data/lib/fx/version.rb +1 -1
- data/lib/fx.rb +40 -0
- data/lib/generators/fx/function/USAGE +2 -0
- data/lib/generators/fx/function/function_generator.rb +54 -39
- data/lib/generators/fx/function/templates/db/migrate/create_function.erb +1 -1
- data/lib/generators/fx/function/templates/db/migrate/update_function.erb +1 -1
- data/lib/generators/fx/migration_helper.rb +45 -0
- data/lib/generators/fx/name_helper.rb +33 -0
- data/lib/generators/fx/trigger/USAGE +2 -0
- data/lib/generators/fx/trigger/templates/db/migrate/create_trigger.erb +1 -1
- data/lib/generators/fx/trigger/templates/db/migrate/update_trigger.erb +1 -1
- data/lib/generators/fx/trigger/trigger_generator.rb +46 -51
- data/lib/generators/fx/version_helper.rb +55 -0
- data/spec/acceptance/user_manages_functions_spec.rb +26 -6
- data/spec/acceptance/user_manages_triggers_spec.rb +11 -11
- data/spec/acceptance_helper.rb +17 -11
- data/spec/dummy/Rakefile +8 -1
- data/spec/dummy/bin/bundle +2 -2
- data/spec/dummy/bin/rails +3 -3
- data/spec/dummy/bin/rake +2 -2
- data/spec/dummy/config/application.rb +2 -0
- data/spec/dummy/config/database.yml +2 -0
- data/spec/dummy/config.ru +1 -1
- data/spec/features/functions/migrations_spec.rb +9 -9
- data/spec/features/functions/revert_spec.rb +13 -13
- data/spec/features/triggers/migrations_spec.rb +11 -11
- data/spec/features/triggers/revert_spec.rb +21 -21
- data/spec/fx/adapters/postgres/functions_spec.rb +40 -0
- data/spec/fx/adapters/postgres/query_executor_spec.rb +75 -0
- data/spec/fx/adapters/postgres/triggers_spec.rb +48 -0
- data/spec/fx/adapters/postgres_spec.rb +115 -111
- data/spec/fx/command_recorder_spec.rb +39 -53
- data/spec/fx/configuration_spec.rb +20 -9
- data/spec/fx/definition_spec.rb +53 -38
- data/spec/fx/function_spec.rb +143 -0
- data/spec/fx/schema_dumper_spec.rb +241 -0
- data/spec/fx/statements_spec.rb +219 -0
- data/spec/fx/trigger_spec.rb +52 -0
- data/spec/fx_spec.rb +28 -0
- data/spec/generators/fx/function/function_generator_spec.rb +22 -10
- data/spec/generators/fx/migration_helper_spec.rb +108 -0
- data/spec/generators/fx/name_helper_spec.rb +114 -0
- data/spec/generators/fx/trigger/trigger_generator_spec.rb +55 -20
- data/spec/generators/fx/version_helper_spec.rb +157 -0
- data/spec/spec_helper.rb +16 -4
- data/spec/support/database_reset.rb +24 -0
- data/spec/support/definition_helpers.rb +5 -9
- data/spec/support/generator_setup.rb +46 -5
- data/spec/support/migration_helpers.rb +9 -1
- data/spec/support/warning_helper.rb +5 -0
- metadata +43 -215
- data/.ruby-version +0 -1
- data/.travis.yml +0 -27
- data/Appraisals +0 -21
- data/bin/appraisal +0 -17
- data/gemfiles/rails40.gemfile +0 -8
- data/gemfiles/rails40.gemfile.lock +0 -111
- data/gemfiles/rails41.gemfile +0 -8
- data/gemfiles/rails41.gemfile.lock +0 -113
- data/gemfiles/rails42.gemfile +0 -8
- data/gemfiles/rails42.gemfile.lock +0 -130
- data/gemfiles/rails50.gemfile +0 -8
- data/gemfiles/rails50.gemfile.lock +0 -126
- data/lib/fx/command_recorder/arguments.rb +0 -43
- data/lib/fx/command_recorder/function.rb +0 -30
- data/lib/fx/command_recorder/trigger.rb +0 -30
- data/lib/fx/schema_dumper/function.rb +0 -29
- data/lib/fx/schema_dumper/trigger.rb +0 -29
- data/lib/fx/statements/function.rb +0 -105
- data/lib/fx/statements/trigger.rb +0 -133
- data/spec/fx/command_recorder/arguments_spec.rb +0 -41
- data/spec/fx/schema_dumper/function_spec.rb +0 -22
- data/spec/fx/schema_dumper/trigger_spec.rb +0 -40
- data/spec/fx/statements/function_spec.rb +0 -103
- data/spec/fx/statements/trigger_spec.rb +0 -132
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a1b25361cfa43280f81e493a4eb518864862dad321878048282ce8f9daad6e1a
|
|
4
|
+
data.tar.gz: ce20ce6b1bb9031b420e78b83ecf23416d50ca44668cf15e0951142e32a0c75e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2e8d5db85fb283586a9d713cdffb6fc50604e85498eeb2c16ac8f63708fabe01a29e03b4157b32f84fe061d4bedb996f4e44db90f5d53d2b655c730352c7c101
|
|
7
|
+
data.tar.gz: 70e6670c67e267f383fa7ed3001350fa3c6548d4bf6183625ee10bf1a5c53cfa5c87cbd9bf231b196524f206d96bf638ba16f6b9020f20803f4ae85685fbf44a
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
#
|
|
3
|
+
# Check if minimum supported dependency versions are at or approaching EOL.
|
|
4
|
+
# Uses the endoflife.date API. Outputs GitHub Actions annotations and opens
|
|
5
|
+
# an issue when action is needed.
|
|
6
|
+
#
|
|
7
|
+
# Environment:
|
|
8
|
+
# WARN_DAYS - days before EOL to start warning (default: 90)
|
|
9
|
+
# GH_TOKEN - GitHub token for creating issues (optional)
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
WARN_DAYS="${WARN_DAYS:-90}"
|
|
14
|
+
|
|
15
|
+
ruby_min=$(ruby -e "
|
|
16
|
+
spec = Gem::Specification.load('fx.gemspec')
|
|
17
|
+
puts spec.required_ruby_version.requirements
|
|
18
|
+
.select { |op, _| op == '>=' }
|
|
19
|
+
.map { |_, v| v.segments[0..1].join('.') }
|
|
20
|
+
.first
|
|
21
|
+
")
|
|
22
|
+
|
|
23
|
+
rails_min=$(ruby -e "
|
|
24
|
+
spec = Gem::Specification.load('fx.gemspec')
|
|
25
|
+
dep = spec.dependencies.find { |d| d.name == 'activerecord' }
|
|
26
|
+
puts dep.requirement.requirements
|
|
27
|
+
.select { |op, _| op == '>=' }
|
|
28
|
+
.map { |_, v| v.segments[0..1].join('.') }
|
|
29
|
+
.first
|
|
30
|
+
")
|
|
31
|
+
|
|
32
|
+
postgres_min=$(ruby -ryaml -e "
|
|
33
|
+
ci = YAML.load_file('.github/workflows/ci.yml')
|
|
34
|
+
versions = ci.dig('jobs', 'tests', 'strategy', 'matrix', 'postgres')
|
|
35
|
+
puts versions.map(&:to_i).min
|
|
36
|
+
")
|
|
37
|
+
|
|
38
|
+
echo "Ruby minimum: $ruby_min"
|
|
39
|
+
echo "Rails minimum: $rails_min"
|
|
40
|
+
echo "PostgreSQL minimum: $postgres_min"
|
|
41
|
+
|
|
42
|
+
alerts=""
|
|
43
|
+
|
|
44
|
+
check_eol() {
|
|
45
|
+
product="$1"
|
|
46
|
+
version="$2"
|
|
47
|
+
|
|
48
|
+
eol_date=$(curl -sf "https://endoflife.date/api/${product}/${version}.json" \
|
|
49
|
+
| ruby -rjson -e '
|
|
50
|
+
data = JSON.parse($stdin.read)
|
|
51
|
+
eol = data["eol"]
|
|
52
|
+
if eol == true
|
|
53
|
+
puts "1970-01-01"
|
|
54
|
+
elsif eol == false
|
|
55
|
+
exit
|
|
56
|
+
else
|
|
57
|
+
puts eol
|
|
58
|
+
end
|
|
59
|
+
') || return 0
|
|
60
|
+
|
|
61
|
+
if [ -z "$eol_date" ]; then
|
|
62
|
+
echo "$product $version: no EOL date set (still supported)"
|
|
63
|
+
return
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
today=$(date -u +%Y-%m-%d)
|
|
67
|
+
warn_date=$(date -u -d "$today + ${WARN_DAYS} days" +%Y-%m-%d 2>/dev/null \
|
|
68
|
+
|| date -u -v+"${WARN_DAYS}"d +%Y-%m-%d)
|
|
69
|
+
|
|
70
|
+
if [ "$eol_date" \< "$today" ] || [ "$eol_date" = "$today" ]; then
|
|
71
|
+
echo "::error::$product $version reached EOL on $eol_date"
|
|
72
|
+
alerts="$alerts- **$product $version** reached EOL on $eol_date\n"
|
|
73
|
+
elif [ "$eol_date" \< "$warn_date" ]; then
|
|
74
|
+
echo "::warning::$product $version reaches EOL on $eol_date (within ${WARN_DAYS} days)"
|
|
75
|
+
alerts="$alerts- **$product $version** reaches EOL on $eol_date (within ${WARN_DAYS} days)\n"
|
|
76
|
+
else
|
|
77
|
+
echo "$product $version: EOL on $eol_date (no action needed)"
|
|
78
|
+
fi
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
check_eol "ruby" "$ruby_min"
|
|
82
|
+
check_eol "rails" "$rails_min"
|
|
83
|
+
check_eol "postgresql" "$postgres_min"
|
|
84
|
+
|
|
85
|
+
if [ -n "$alerts" ]; then
|
|
86
|
+
title="Dependency EOL alert"
|
|
87
|
+
body=$(printf "The following minimum supported versions are at or approaching end-of-life:\n\n%b\n\nConsider bumping the minimum version in \`fx.gemspec\` and updating the CI matrix." "$alerts")
|
|
88
|
+
|
|
89
|
+
existing=$(gh issue list --state open --search "$title" --json number --jq '.[0].number' 2>/dev/null || true)
|
|
90
|
+
if [ -n "$existing" ]; then
|
|
91
|
+
echo "Issue #$existing already open, skipping creation"
|
|
92
|
+
else
|
|
93
|
+
gh issue create --title "$title" --body "$body"
|
|
94
|
+
fi
|
|
95
|
+
fi
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: master
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: "*"
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
tests:
|
|
11
|
+
name: "ruby ${{ matrix.ruby }} / rails ${{ matrix.rails }} / postgres ${{ matrix.postgres }}"
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
ruby: ["3.3", "4.0"]
|
|
18
|
+
rails: ["7.2", "8.1"]
|
|
19
|
+
postgres: ["14", "18"]
|
|
20
|
+
include:
|
|
21
|
+
- ruby: "4.0"
|
|
22
|
+
rails: "main"
|
|
23
|
+
postgres: "18"
|
|
24
|
+
allow-failure: true
|
|
25
|
+
|
|
26
|
+
continue-on-error: ${{ matrix.allow-failure || false }}
|
|
27
|
+
|
|
28
|
+
services:
|
|
29
|
+
postgres:
|
|
30
|
+
image: postgres:${{ matrix.postgres }}
|
|
31
|
+
env:
|
|
32
|
+
POSTGRES_USER: postgres
|
|
33
|
+
POSTGRES_HOST_AUTH_METHOD: trust
|
|
34
|
+
ports:
|
|
35
|
+
- 5432:5432
|
|
36
|
+
# Set health checks to wait until postgres has started
|
|
37
|
+
options: >-
|
|
38
|
+
--health-cmd pg_isready
|
|
39
|
+
--health-interval 10s
|
|
40
|
+
--health-timeout 5s
|
|
41
|
+
--health-retries 5
|
|
42
|
+
|
|
43
|
+
env:
|
|
44
|
+
POSTGRES_USER: postgres
|
|
45
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
|
46
|
+
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v6
|
|
49
|
+
|
|
50
|
+
- name: Set up Ruby
|
|
51
|
+
uses: ruby/setup-ruby@v1
|
|
52
|
+
with:
|
|
53
|
+
ruby-version: ${{ matrix.ruby }}
|
|
54
|
+
bundler-cache: true
|
|
55
|
+
rubygems: latest
|
|
56
|
+
|
|
57
|
+
- name: Setup environment
|
|
58
|
+
run: bin/setup
|
|
59
|
+
|
|
60
|
+
- name: Run tests
|
|
61
|
+
run: bundle exec rake
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: EOL Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 9 1 * *" # 1st of each month at 09:00 UTC
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
warn_days:
|
|
9
|
+
description: "Days before EOL to start warning"
|
|
10
|
+
required: false
|
|
11
|
+
default: "90"
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
issues: write
|
|
15
|
+
|
|
16
|
+
env:
|
|
17
|
+
WARN_DAYS: ${{ inputs.warn_days || '90' }}
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
check:
|
|
21
|
+
name: Check dependency EOL status
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v6
|
|
26
|
+
|
|
27
|
+
- name: Check EOL status
|
|
28
|
+
env:
|
|
29
|
+
GH_TOKEN: ${{ github.token }}
|
|
30
|
+
run: .github/scripts/check-eol
|
data/.rspec
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
--color
|
|
1
|
+
--no-color
|
|
2
2
|
--require spec_helper
|
data/.standard.yml
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
The noteworthy changes for each version are included here. For a complete
|
|
4
|
+
changelog, see the [commits] for each version via the version links.
|
|
5
|
+
|
|
6
|
+
[commits]: https://github.com/teoljungberg/fx/commits/master
|
|
7
|
+
|
|
8
|
+
## [0.11.0]
|
|
9
|
+
|
|
10
|
+
[0.11.0]: https://github.com/teoljungberg/fx/compare/v0.10.2...v0.11.0
|
|
11
|
+
|
|
12
|
+
- Drop EOL Ruby 3.2 (#212)
|
|
13
|
+
- Add `Function#signature` for PostgreSQL function identity (#207)
|
|
14
|
+
- Add PostgreSQL versioning policy, officially supporting PostgreSQL 14-18 (#194)
|
|
15
|
+
- Refactor Statements module to use explicit keyword arguments instead of `**options` hash (#186)
|
|
16
|
+
- Internal refactorings / improvements
|
|
17
|
+
- Add scheduled EOL check for Ruby, Rails, and PostgreSQL (#205)
|
|
18
|
+
- Add GitHub release creation to release task (#209)
|
|
19
|
+
- Add PostgreSQL 18 to CI test matrix (#194)
|
|
20
|
+
- Default `support_drop_function_without_args` to `true` (#194)
|
|
21
|
+
- Document adapter subclass pattern for custom schema dump ordering (#211)
|
|
22
|
+
- Remove duplicate command recorder specs (#202)
|
|
23
|
+
|
|
24
|
+
## [0.10.2]
|
|
25
|
+
|
|
26
|
+
[0.10.2]: https://github.com/teoljungberg/fx/compare/v0.10.1...v0.10.2
|
|
27
|
+
|
|
28
|
+
- Remove upper bound on Rails dependency (#198)
|
|
29
|
+
- Internal refactorings / improvements
|
|
30
|
+
- Add Rails main to CI matrix
|
|
31
|
+
|
|
32
|
+
## [0.10.1]
|
|
33
|
+
|
|
34
|
+
[0.10.1]: https://github.com/teoljungberg/fx/compare/v0.10.0...v0.10.1
|
|
35
|
+
|
|
36
|
+
- Fix spacing between functions and triggers in schema.rb (#195)
|
|
37
|
+
- Remove `database_cleaner` dependency (#190)
|
|
38
|
+
- Internal refactorings / improvements
|
|
39
|
+
- Improve schema dumper test coverage
|
|
40
|
+
- Use methods over instance variables (#192)
|
|
41
|
+
- Write out fully qualified path in definitions (#189)
|
|
42
|
+
- Improve test isolation with schema reset (#190)
|
|
43
|
+
- Rewrite shell command chains (#188)
|
|
44
|
+
- Inline `active_record_migration_class` (#187)
|
|
45
|
+
- Add Ruby 4.0 to CI matrix (#193)
|
|
46
|
+
- Minimize CI matrix to boundary versions (#196)
|
|
47
|
+
|
|
48
|
+
## [0.10.0]
|
|
49
|
+
|
|
50
|
+
[0.10.0]: https://github.com/teoljungberg/fx/compare/v0.9.0...v0.10.0
|
|
51
|
+
|
|
52
|
+
- Scope functions and triggers to schema search path (#168)
|
|
53
|
+
- Ensure multi-schema dumping in Rails 8.1.0 does not dump the same objects for
|
|
54
|
+
all schemas (#177)
|
|
55
|
+
- Require Ruby >= 3.2 (#166)
|
|
56
|
+
- Require Ruby >= 3.1 (#162)
|
|
57
|
+
- New version support
|
|
58
|
+
- Add Rails 8.1 to the test matrix (#175)
|
|
59
|
+
- Add Ruby 3.4 to the test matrix (#161)
|
|
60
|
+
- Removed version support
|
|
61
|
+
- Drop Rails 7.1 due to EOL (#176)
|
|
62
|
+
- Drop EOL Ruby versions (3.0) (#162)
|
|
63
|
+
- Drop EOL Rails versions (7.0) (#162)
|
|
64
|
+
- Internal refactorings / improvements
|
|
65
|
+
- Extract validation methods in `Statements` module (#184)
|
|
66
|
+
- Refactor generators with helper classes and improvements (#183)
|
|
67
|
+
- Extract `QueryExecutor` to remove duplication (#182)
|
|
68
|
+
- Extract PostgreSQL version constants (#181)
|
|
69
|
+
- YARD documentation improvements (#179)
|
|
70
|
+
- Ensure fx has been loaded (#173)
|
|
71
|
+
- Replace ammeter (#172)
|
|
72
|
+
- Remove teardown phase (#171)
|
|
73
|
+
|
|
74
|
+
## [0.9.0]
|
|
75
|
+
|
|
76
|
+
[0.9.0]: https://github.com/teoljungberg/fx/compare/v0.8.0...v0.9.0
|
|
77
|
+
|
|
78
|
+
- Drop EOL Rails versions (6.2)
|
|
79
|
+
- Add Ruby 3.4.0 preview's to the test matrix (#152)
|
|
80
|
+
- Add Rails 8.0.0 to the test matrix (#152)
|
|
81
|
+
- Add Rails 7.2 to the test matrix (#150)
|
|
82
|
+
- Fix deprecation warnings in Rails (#148)
|
|
83
|
+
- Mark `Fx::CommandRecorder::Arguments` as private.
|
|
84
|
+
- Add Ruby 3.3 to the test matrix (#144)
|
|
85
|
+
- Internal refactorings:
|
|
86
|
+
- Move development dependencies to Gemfile (#145)
|
|
87
|
+
- Inline `Fx::CommandRecorder::Arguments`
|
|
88
|
+
- Inline `Fx::{CommandRecorder,SchemaDumper,Statements}::{Function,Trigger}`
|
|
89
|
+
- Move configuration methods to `Fx`
|
|
90
|
+
- Add `Fx::Definition.{function,trigger}` (#119)
|
|
91
|
+
- Add Rails 7.1 to the test matrix (#136)
|
|
92
|
+
- Add Rubygems metadata to gemspec (#132)
|
|
93
|
+
- Disable RSpec's monkey patching (#121)
|
|
94
|
+
- Raise on warnings (#124)
|
|
95
|
+
- Require Ruby >= 3.0 (#128)
|
|
96
|
+
- Require Rails >= 6.1 (#127)
|
|
97
|
+
|
|
98
|
+
## [0.8.0]
|
|
99
|
+
|
|
100
|
+
[0.8.0]: https://github.com/teoljungberg/fx/compare/v0.7.0...v0.8.0
|
|
101
|
+
|
|
102
|
+
- Replace Travis CI with GitHub Actions.
|
|
103
|
+
- Bump minimum Ruby version to 2.7.
|
|
104
|
+
- Ruby 2.7 will be dropped in end of March 2023, so a release to drop it will
|
|
105
|
+
happen afterwards.
|
|
106
|
+
- Bump minimum Rails version to 6.0.0
|
|
107
|
+
- Rails 6.0 will be dropped in June 2023, so a release to drop it will happen
|
|
108
|
+
afterwards
|
|
109
|
+
- Adopt standard.rb
|
|
110
|
+
- Contributing improvements
|
|
111
|
+
- Test-suite improvements
|
|
112
|
+
|
|
113
|
+
## [0.7.0]
|
|
114
|
+
|
|
115
|
+
[0.7.0]: https://github.com/teoljungberg/fx/compare/v0.6.2...v0.7.0
|
|
116
|
+
|
|
117
|
+
- Support Ruby 3 (#76)
|
|
118
|
+
- Preserve backslashes when dumping the schema (#71)
|
|
119
|
+
- Add a link to F(x) SqlServer Adapter in the README (#80)
|
|
120
|
+
|
|
121
|
+
## [0.6.2]
|
|
122
|
+
|
|
123
|
+
[0.6.2]: https://github.com/teoljungberg/fx/compare/v0.6.1...v0.6.2
|
|
124
|
+
|
|
125
|
+
- Add support for Ruby 3
|
|
126
|
+
|
|
127
|
+
## [0.6.1]
|
|
128
|
+
|
|
129
|
+
[0.6.1]: https://github.com/teoljungberg/fx/compare/v0.6.0...v0.6.1
|
|
130
|
+
|
|
131
|
+
- Fix: Support --no-migration generator flag (#62)
|
|
132
|
+
|
|
133
|
+
## [0.6.0]
|
|
134
|
+
|
|
135
|
+
[0.6.0]: https://github.com/teoljungberg/fx/compare/v0.5.0...v0.6.0
|
|
136
|
+
|
|
137
|
+
- Support unique functions with parameters (#27)
|
|
138
|
+
- Use db connection provided by Rails (#49)
|
|
139
|
+
- Support `--no-migration` generator flag (#60)
|
|
140
|
+
- Use current ActiveRecord version in migrations (#59)
|
|
141
|
+
- Does not include aggregates when dumping schema (#50)
|
|
142
|
+
- Dump functions in the beginning of the schema (#53)
|
|
143
|
+
|
|
144
|
+
## [0.5.0]
|
|
145
|
+
|
|
146
|
+
[0.5.0]: https://github.com/teoljungberg/fx/compare/v0.4.0...v0.5.0
|
|
147
|
+
|
|
148
|
+
- Drop EOL Ruby versions.
|
|
149
|
+
- Drop EOL Rails versions.
|
|
150
|
+
|
|
151
|
+
## [0.4.0]
|
|
152
|
+
|
|
153
|
+
[0.4.0]: https://github.com/teoljungberg/fx/compare/v0.3.1...v0.4.0
|
|
154
|
+
|
|
155
|
+
- Add table_name to README (#15)
|
|
156
|
+
- Reverse function/trigger order in README (#17)
|
|
157
|
+
- Split up Trigger#definition test (#19)
|
|
158
|
+
- Find definitions in engines (#18)
|
|
159
|
+
|
|
160
|
+
## [0.3.1]
|
|
161
|
+
|
|
162
|
+
[0.3.1]: https://github.com/teoljungberg/fx/compare/v0.3.0...v0.3.1
|
|
163
|
+
|
|
164
|
+
- Strip shared leading whitespace from sql_definitions (#13)
|
|
165
|
+
- Update documentation for `drop_function`
|
|
166
|
+
- Document `Fx::Adapters::Postgres#initialize`
|
|
167
|
+
- Fix test suite issues:
|
|
168
|
+
- Add unit test coverage for `Fx::Adapters::Triggers`
|
|
169
|
+
- Add unit test coverage for `Fx::Adapters::Functions`
|
|
170
|
+
- Add unit test coverage for `Fx::Trigger`
|
|
171
|
+
- Add unit test coverage for `Fx::Function`
|
|
172
|
+
|
|
173
|
+
## [0.3.0]
|
|
174
|
+
|
|
175
|
+
[0.3.0]: https://github.com/teoljungberg/fx/compare/v0.2.0...v0.3.0
|
|
176
|
+
|
|
177
|
+
## [0.2.0]
|
|
178
|
+
|
|
179
|
+
[0.2.0]: https://github.com/teoljungberg/fx/compare/v0.1.0...v0.2.0
|
|
180
|
+
|
|
181
|
+
## [0.1.0]
|
|
182
|
+
|
|
183
|
+
F(x) adds methods to `ActiveRecord::Migration` to create and manage database
|
|
184
|
+
functions and triggers in Rails.
|
|
185
|
+
|
|
186
|
+
[0.1.0]: https://github.com/teoljungberg/fx/compare/4ccf986643d9de82038977eff8c6b1a4a716d698...v0.1.0
|
data/CONTRIBUTING.md
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
+
We love contributions from everyone. By participating in this project, you
|
|
4
|
+
agree to abide by our [code of conduct].
|
|
5
|
+
|
|
6
|
+
[code of conduct]: https://thoughtbot.com/open-source-code-of-conduct
|
|
7
|
+
|
|
8
|
+
## Contributing Code
|
|
9
|
+
|
|
3
10
|
1. Fork the repository.
|
|
4
11
|
2. Run `bin/setup`, which will install dependencies and create the dummy
|
|
5
12
|
application database.
|
|
6
|
-
3. Run `
|
|
7
|
-
|
|
8
|
-
4. Make your change with new passing tests, following
|
|
13
|
+
3. Run `rake` to verify that the tests pass against the version of Rails you are
|
|
14
|
+
running locally.
|
|
15
|
+
4. Make your change with new passing tests, following existing style.
|
|
9
16
|
5. Write a [good commit message], push your fork, and submit a pull request.
|
|
17
|
+
6. CI will run the test suite on all configured versions of Ruby and Rails.
|
|
18
|
+
Address any failures.
|
|
10
19
|
|
|
11
20
|
[good commit message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
|
12
21
|
|
|
13
|
-
Others will give constructive feedback.
|
|
22
|
+
Others will give constructive feedback. This is a time for discussion and
|
|
14
23
|
improvements, and making the necessary changes will be required before we can
|
|
15
24
|
merge the contribution.
|
data/Gemfile
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
source
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
rails_version = ENV.fetch("RAILS_VERSION", "8.1")
|
|
2
4
|
|
|
3
|
-
# Specify your gem's dependencies in fx.gemspec
|
|
4
5
|
gemspec
|
|
6
|
+
|
|
7
|
+
if rails_version == "main"
|
|
8
|
+
gem "activerecord", github: "rails/rails", branch: "main"
|
|
9
|
+
gem "railties", github: "rails/rails", branch: "main"
|
|
10
|
+
else
|
|
11
|
+
gem "activerecord", "~> #{rails_version}.0"
|
|
12
|
+
gem "railties", "~> #{rails_version}.0"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
gem "bundler", ">= 1.5"
|
|
16
|
+
gem "pg"
|
|
17
|
+
gem "pry"
|
|
18
|
+
gem "rake"
|
|
19
|
+
gem "redcarpet"
|
|
20
|
+
gem "rspec", ">= 3.3"
|
|
21
|
+
gem "standardrb"
|
|
22
|
+
gem "yard"
|
|
23
|
+
gem "warning"
|
data/LICENSE
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Copyright 2016 Teo Ljungberg
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
+
the Software without restriction, including without limitation the rights to
|
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
7
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
15
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# F(x)
|
|
2
2
|
|
|
3
|
+
[](https://github.com/teoljungberg/fx/actions/workflows/ci.yml)
|
|
4
|
+
|
|
3
5
|
F(x) adds methods to `ActiveRecord::Migration` to create and manage database
|
|
4
6
|
functions and triggers in Rails.
|
|
5
7
|
|
|
@@ -18,33 +20,35 @@ F(x) ships with support for PostgreSQL. The adapter is configurable (see
|
|
|
18
20
|
|
|
19
21
|
## Great, how do I create a trigger and a function?
|
|
20
22
|
|
|
21
|
-
You've got this great idea for a
|
|
23
|
+
You've got this great idea for a function you'd like to call
|
|
22
24
|
`uppercase_users_name`. You can create the migration and the corresponding
|
|
23
25
|
definition file with the following command:
|
|
24
26
|
|
|
25
27
|
```sh
|
|
26
|
-
% rails generate fx:
|
|
28
|
+
% rails generate fx:function uppercase_users_name
|
|
29
|
+
create db/functions/uppercase_users_name_v01.sql
|
|
30
|
+
create db/migrate/[TIMESTAMP]_create_function_uppercase_users_name.rb
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Edit the `db/functions/uppercase_users_name_v01.sql` file with the SQL statement
|
|
34
|
+
that defines your function.
|
|
35
|
+
|
|
36
|
+
Next, let's add a trigger called `uppercase_users_name` to call our new
|
|
37
|
+
function each time we `INSERT` on the `users` table.
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
% rails generate fx:trigger uppercase_users_name table_name:users
|
|
27
41
|
create db/triggers/uppercase_users_name_v01.sql
|
|
28
42
|
create db/migrate/[TIMESTAMP]_create_trigger_uppercase_users_name.rb
|
|
29
43
|
```
|
|
30
44
|
|
|
31
|
-
|
|
32
|
-
that defines your trigger. In our example, this might look something like this:
|
|
45
|
+
In our example, this might look something like this:
|
|
33
46
|
|
|
34
47
|
```sql
|
|
35
48
|
CREATE TRIGGER uppercase_users_name
|
|
36
49
|
BEFORE INSERT ON users
|
|
37
50
|
FOR EACH ROW
|
|
38
|
-
EXECUTE
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
As you see, we execute a function called `uppercase_users_name` before each
|
|
42
|
-
`INSERT` on the `users` table, which is a function we don't have yet.
|
|
43
|
-
|
|
44
|
-
```sh
|
|
45
|
-
% rails generate fx:function uppercase_users_name
|
|
46
|
-
create db/functions/uppercase_users_name_v01.sql
|
|
47
|
-
create db/migrate/[TIMESTAMP]_create_function_uppercase_users_name.rb
|
|
51
|
+
EXECUTE FUNCTION uppercase_users_name();
|
|
48
52
|
```
|
|
49
53
|
|
|
50
54
|
The generated migrations contains `create_function` and `create_trigger`
|
|
@@ -79,3 +83,84 @@ def change
|
|
|
79
83
|
drop_function :uppercase_users_name, revert_to_version: 2
|
|
80
84
|
end
|
|
81
85
|
```
|
|
86
|
+
|
|
87
|
+
## What if I need to use a function as the default value of a column?
|
|
88
|
+
|
|
89
|
+
You need to set F(x) to dump the functions in the beginning of db/schema.rb in a
|
|
90
|
+
initializer:
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
# config/initializers/fx.rb
|
|
94
|
+
Fx.configure do |config|
|
|
95
|
+
config.dump_functions_at_beginning_of_schema = true
|
|
96
|
+
end
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
And then you can use a lambda in your migration file:
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
create_table :my_table do |t|
|
|
103
|
+
t.string :my_column, default: -> { "my_function()" }
|
|
104
|
+
end
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
That's how you tell Rails to use the default as a literal SQL for the default
|
|
108
|
+
column value instead of a plain string.
|
|
109
|
+
|
|
110
|
+
## Customizing Schema Dump Order
|
|
111
|
+
|
|
112
|
+
By default, functions and triggers are dumped to `schema.rb` in the order
|
|
113
|
+
returned by the database. If you need a specific ordering (e.g., alphabetical
|
|
114
|
+
for deterministic diffs), subclass the adapter and override `#functions` or
|
|
115
|
+
`#triggers`. These methods are part of the adapter's public API and will remain
|
|
116
|
+
stable across releases:
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
# config/initializers/fx.rb
|
|
120
|
+
class SortedPostgresAdapter < Fx::Adapters::Postgres
|
|
121
|
+
def functions
|
|
122
|
+
super.sort_by(&:name)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def triggers
|
|
126
|
+
super.sort_by(&:name)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
Fx.configure do |config|
|
|
131
|
+
config.database = SortedPostgresAdapter.new
|
|
132
|
+
end
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The same approach works for more advanced ordering. For example, if your
|
|
136
|
+
functions depend on each other and need to be dumped in dependency order, you
|
|
137
|
+
could use Ruby's built-in `TSort` to topologically sort them.
|
|
138
|
+
|
|
139
|
+
## Plugins/Adapters
|
|
140
|
+
|
|
141
|
+
- [MySQL](https://github.com/f-mer/fx-adapters-mysql/)
|
|
142
|
+
- [Oracle](https://github.com/zygotecnologia/fx-oracle-adapter)
|
|
143
|
+
- [SQLserver](https://github.com/tarellel/fx-sqlserver-adapter)
|
|
144
|
+
|
|
145
|
+
## Version Support
|
|
146
|
+
|
|
147
|
+
F(x) follows the maintenance policies of Ruby, Rails, and PostgreSQL, supporting
|
|
148
|
+
versions within their official maintenance windows.
|
|
149
|
+
|
|
150
|
+
**Ruby:** 3.3+ ([maintenance branches])
|
|
151
|
+
|
|
152
|
+
**Rails:** 7.2, 8.0, 8.1 ([maintenance policy])
|
|
153
|
+
|
|
154
|
+
**PostgreSQL:** 14, 15, 16, 17, 18 ([versioning policy])
|
|
155
|
+
|
|
156
|
+
When a version reaches end-of-life, support will be dropped in the next minor
|
|
157
|
+
release of F(x). Older versions may continue to work but are not tested or
|
|
158
|
+
guaranteed.
|
|
159
|
+
|
|
160
|
+
[maintenance branches]: https://www.ruby-lang.org/en/downloads/branches/
|
|
161
|
+
[maintenance policy]: https://rubyonrails.org/maintenance
|
|
162
|
+
[versioning policy]: https://www.postgresql.org/support/versioning/
|
|
163
|
+
|
|
164
|
+
## Contributing
|
|
165
|
+
|
|
166
|
+
See [contributing](CONTRIBUTING.md) for more details.
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
2
|
require "rspec/core/rake_task"
|
|
3
|
+
require "standard/rake"
|
|
4
|
+
|
|
5
|
+
Rake::Task["release"].enhance do
|
|
6
|
+
unless system("which gh > /dev/null 2>&1")
|
|
7
|
+
abort "gh CLI is not installed. Install it to create GitHub releases."
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
tag = "v#{Fx::VERSION}"
|
|
11
|
+
sh "gh release create #{tag} --verify-tag -t #{tag} --generate-notes"
|
|
12
|
+
end
|
|
3
13
|
|
|
4
14
|
namespace :dummy do
|
|
5
15
|
require_relative "spec/dummy/config/application"
|
|
@@ -20,4 +30,4 @@ RSpec::Core::RakeTask.new("spec:acceptance") do |task|
|
|
|
20
30
|
end
|
|
21
31
|
|
|
22
32
|
desc "Run the specs and acceptance tests"
|
|
23
|
-
task default: %w
|
|
33
|
+
task default: %w[spec spec:acceptance standard]
|
data/bin/rake
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
|
|
3
4
|
#
|
|
4
5
|
# This file was generated by Bundler.
|
|
5
6
|
#
|
|
@@ -7,9 +8,7 @@
|
|
|
7
8
|
# this file is here to facilitate running it.
|
|
8
9
|
#
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
|
12
|
-
Pathname.new(__FILE__).realpath)
|
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
|
13
12
|
|
|
14
13
|
require "rubygems"
|
|
15
14
|
require "bundler/setup"
|
data/bin/rspec
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
|
+
|
|
3
4
|
#
|
|
4
5
|
# This file was generated by Bundler.
|
|
5
6
|
#
|
|
@@ -7,9 +8,18 @@
|
|
|
7
8
|
# this file is here to facilitate running it.
|
|
8
9
|
#
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
|
12
|
+
|
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
|
14
|
+
|
|
15
|
+
if File.file?(bundle_binstub)
|
|
16
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
|
17
|
+
load(bundle_binstub)
|
|
18
|
+
else
|
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
13
23
|
|
|
14
24
|
require "rubygems"
|
|
15
25
|
require "bundler/setup"
|