activerecord-postgresql-branched 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +11 -3
- data/README.md +11 -2
- data/lib/active_record/connection_adapters/postgresql/branched/adapter.rb +4 -3
- data/lib/active_record/connection_adapters/postgresql/branched/branch_manager.rb +17 -0
- data/lib/active_record/connection_adapters/postgresql/branched/railtie.rb +18 -2
- data/lib/active_record/connection_adapters/postgresql/branched/schema_dumper.rb +2 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1742fc285cfd6d57e93baa73da6dd675fa3b75df1f02a3320fae25bcfe08f28d
|
|
4
|
+
data.tar.gz: 2ee36f561b9a1e9b4b555f48e39499189bd0da2bbf4344bb2b52616869d52008
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 623f743e34d6db55c2b9b3b447dcf1b2b7066d9aad8d05f656580dcf5546a6e20f142ee35d2a7f7f9a7260eea9b2dcb76e78d35006eb1ecf54d8b604d6af0f98
|
|
7
|
+
data.tar.gz: c48eefaa0809be95fdda529956160f85ba240afb0ac97b94c983d80648d4ba7bce5eab35050d100c21ffee5538f93b219bcee8db2059d7df8c442846f78ef091
|
data/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
- Restore primary branch — the primary branch (default: `main`) writes to `public` so feature branches see shared state via `search_path` fallthrough
|
|
6
|
+
- Comprehensive test suite: workflow tests, full DDL coverage (69 tests, 163 assertions)
|
|
7
|
+
- Rewrite README from first principles
|
|
8
|
+
|
|
3
9
|
## 0.3.0
|
|
4
10
|
|
|
5
|
-
- Remove primary branch concept — every branch gets its own schema equally
|
|
6
|
-
- Add shadow interception for `add_foreign_key`, `remove_foreign_key`, `add_check_constraint`, `remove_check_constraint`, `validate_foreign_key`, `validate_check_constraint`
|
|
7
11
|
- Add `db:branch:console` rake task — opens psql with the branch `search_path`
|
|
12
|
+
|
|
13
|
+
## 0.2.0
|
|
14
|
+
|
|
15
|
+
- Add shadow interception for `add_foreign_key`, `remove_foreign_key`, `add_check_constraint`, `remove_check_constraint`, `validate_foreign_key`, `validate_check_constraint`
|
|
8
16
|
- Simplify branch resolution to `PGBRANCH` env var with git fallback
|
|
9
17
|
- Remove `branch_override` config option and `BRANCH` env var
|
|
10
18
|
- `db:branch:prune` accepts `KEEP=branch1,branch2` for explicit control
|
|
11
19
|
- Fix railtie to reuse the adapter's existing BranchManager
|
|
12
|
-
-
|
|
20
|
+
- Pass shadow to `activate` instead of creating a redundant instance
|
|
13
21
|
- Quote schema identifiers consistently in shadow SQL
|
|
14
22
|
|
|
15
23
|
## 0.1.0
|
data/README.md
CHANGED
|
@@ -117,7 +117,7 @@ rails db:branch:discard BRANCH=agent-0
|
|
|
117
117
|
## Rake tasks
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
rails db:branch:reset
|
|
120
|
+
rails db:branch:reset # drop and recreate current branch schema
|
|
121
121
|
rails db:branch:discard # drop current branch schema (or BRANCH=name)
|
|
122
122
|
rails db:branch:list # list all branch schemas and their sizes
|
|
123
123
|
rails db:branch:diff # show tables in the current branch schema
|
|
@@ -131,13 +131,22 @@ rails db:branch:console # open psql with the branch search_path
|
|
|
131
131
|
|
|
132
132
|
## Configuration
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
```yaml
|
|
135
|
+
development:
|
|
136
|
+
adapter: postgresql_branched
|
|
137
|
+
database: myapp_development
|
|
138
|
+
primary_branch: main # default, can be 'master', 'trunk', etc.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The adapter needs a branch name. Resolution order:
|
|
135
142
|
|
|
136
143
|
1. `PGBRANCH` environment variable
|
|
137
144
|
2. `git branch --show-current` (automatic fallback)
|
|
138
145
|
|
|
139
146
|
If neither is available, the adapter raises an error.
|
|
140
147
|
|
|
148
|
+
On the **primary branch** (`main` by default), the adapter stands aside entirely. No branch schema is created. Migrations land directly in `public`. This is how the shared baseline advances — when you pull main and run `db:migrate`, the tables go to `public` where every feature branch can see them via `search_path` fallthrough.
|
|
149
|
+
|
|
141
150
|
All standard PostgreSQL connection parameters work as normal (`host`, `port`, `username`, `password`, etc.).
|
|
142
151
|
|
|
143
152
|
**Do not set `schema_search_path` in database.yml** — it conflicts with the adapter's `search_path` management.
|
|
@@ -31,7 +31,7 @@ module ActiveRecord
|
|
|
31
31
|
def initialize(...)
|
|
32
32
|
super
|
|
33
33
|
@branch_manager = BranchManager.new(self, @config)
|
|
34
|
-
@shadow = Shadow.new(self, @branch_manager.branch_schema)
|
|
34
|
+
@shadow = Shadow.new(self, @branch_manager.branch_schema) unless @branch_manager.primary_branch?
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def configure_connection
|
|
@@ -41,7 +41,7 @@ module ActiveRecord
|
|
|
41
41
|
|
|
42
42
|
SHADOW_BEFORE.each do |method|
|
|
43
43
|
define_method(method) do |table_name, *args, **kwargs, &block|
|
|
44
|
-
@shadow
|
|
44
|
+
@shadow&.call(table_name)
|
|
45
45
|
super(table_name, *args, **kwargs, &block)
|
|
46
46
|
end
|
|
47
47
|
end
|
|
@@ -51,9 +51,10 @@ module ActiveRecord
|
|
|
51
51
|
# the branch schema. The table and index renames succeed before the
|
|
52
52
|
# sequence rename fails, so we rescue the sequence error.
|
|
53
53
|
def rename_table(table_name, new_name, **options)
|
|
54
|
-
@shadow
|
|
54
|
+
@shadow&.call(table_name)
|
|
55
55
|
super
|
|
56
56
|
rescue ActiveRecord::StatementInvalid => e
|
|
57
|
+
raise if @branch_manager.primary_branch?
|
|
57
58
|
raise unless e.cause.is_a?(PG::UndefinedTable)
|
|
58
59
|
end
|
|
59
60
|
|
|
@@ -13,11 +13,17 @@ module ActiveRecord
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def activate(shadow)
|
|
16
|
+
return if primary_branch?
|
|
17
|
+
|
|
16
18
|
ensure_schema
|
|
17
19
|
set_search_path
|
|
18
20
|
shadow_migration_tables(shadow)
|
|
19
21
|
end
|
|
20
22
|
|
|
23
|
+
def primary_branch?
|
|
24
|
+
@branch == primary_branch_name
|
|
25
|
+
end
|
|
26
|
+
|
|
21
27
|
def reset
|
|
22
28
|
drop_schema
|
|
23
29
|
ensure_schema
|
|
@@ -26,6 +32,11 @@ module ActiveRecord
|
|
|
26
32
|
|
|
27
33
|
def discard(branch_name = @branch)
|
|
28
34
|
schema = self.class.sanitise(branch_name)
|
|
35
|
+
|
|
36
|
+
if schema == self.class.sanitise(primary_branch_name)
|
|
37
|
+
raise "Cannot discard the primary branch schema"
|
|
38
|
+
end
|
|
39
|
+
|
|
29
40
|
@connection.execute("DROP SCHEMA IF EXISTS #{quote(schema)} CASCADE")
|
|
30
41
|
end
|
|
31
42
|
|
|
@@ -45,6 +56,8 @@ module ActiveRecord
|
|
|
45
56
|
end
|
|
46
57
|
|
|
47
58
|
def diff
|
|
59
|
+
return [] if primary_branch?
|
|
60
|
+
|
|
48
61
|
@connection.select_values(<<~SQL)
|
|
49
62
|
SELECT table_name FROM information_schema.tables
|
|
50
63
|
WHERE table_schema = #{@connection.quote(@branch_schema)}
|
|
@@ -107,6 +120,10 @@ module ActiveRecord
|
|
|
107
120
|
name
|
|
108
121
|
end
|
|
109
122
|
|
|
123
|
+
def primary_branch_name
|
|
124
|
+
(@config[:primary_branch] || "main").to_s
|
|
125
|
+
end
|
|
126
|
+
|
|
110
127
|
def ensure_schema
|
|
111
128
|
@connection.execute("CREATE SCHEMA IF NOT EXISTS #{quote(@branch_schema)}")
|
|
112
129
|
end
|
|
@@ -9,6 +9,12 @@ module ActiveRecord
|
|
|
9
9
|
desc "Drop and recreate the current branch schema"
|
|
10
10
|
task reset: :load_config do
|
|
11
11
|
manager = branch_manager
|
|
12
|
+
|
|
13
|
+
if manager.primary_branch?
|
|
14
|
+
puts "On primary branch (#{manager.branch}), nothing to reset."
|
|
15
|
+
next
|
|
16
|
+
end
|
|
17
|
+
|
|
12
18
|
manager.reset
|
|
13
19
|
puts "Reset branch schema #{manager.branch_schema}. Run db:migrate to reapply branch migrations."
|
|
14
20
|
end
|
|
@@ -53,6 +59,12 @@ module ActiveRecord
|
|
|
53
59
|
desc "Show objects in the current branch schema"
|
|
54
60
|
task diff: :load_config do
|
|
55
61
|
manager = branch_manager
|
|
62
|
+
|
|
63
|
+
if manager.primary_branch?
|
|
64
|
+
puts "On primary branch, no diff."
|
|
65
|
+
next
|
|
66
|
+
end
|
|
67
|
+
|
|
56
68
|
tables = manager.diff
|
|
57
69
|
|
|
58
70
|
if tables.empty?
|
|
@@ -68,14 +80,18 @@ module ActiveRecord
|
|
|
68
80
|
manager = branch_manager
|
|
69
81
|
config = ActiveRecord::Base.connection_db_config.configuration_hash
|
|
70
82
|
|
|
71
|
-
env = {
|
|
83
|
+
env = {}
|
|
84
|
+
unless manager.primary_branch?
|
|
85
|
+
env["PGOPTIONS"] = "-c search_path=#{manager.branch_schema},public"
|
|
86
|
+
end
|
|
87
|
+
|
|
72
88
|
args = ["psql"]
|
|
73
89
|
args.push("-h", config[:host].to_s) if config[:host]
|
|
74
90
|
args.push("-p", config[:port].to_s) if config[:port]
|
|
75
91
|
args.push("-U", config[:username].to_s) if config[:username]
|
|
76
92
|
args.push(config[:database].to_s)
|
|
77
93
|
|
|
78
|
-
puts "Connecting to #{config[:database]} as #{manager.branch_schema}..."
|
|
94
|
+
puts "Connecting to #{config[:database]}#{" as #{manager.branch_schema}" unless manager.primary_branch?}..."
|
|
79
95
|
exec(env, *args)
|
|
80
96
|
end
|
|
81
97
|
end
|