Module: Polyrun::Database::UrlBuilder
- Defined in:
- lib/polyrun/database/url_builder.rb,
lib/polyrun/database/url_builder/connection.rb,
lib/polyrun/database/url_builder/connection/infer.rb,
lib/polyrun/database/url_builder/template_prepare.rb,
lib/polyrun/database/url_builder/connection/url_builders.rb
Overview
Builds database URLs from polyrun.yml databases (spec2 §5.2) — no Liquid; use ENV fallbacks. Use adapter: or nested blocks: postgresql, mysql / mysql2 / trilogy, sqlserver / mssql, sqlite3 / sqlite, mongodb / mongo.
Defined Under Namespace
Modules: Connection, ConnectionInfer, ConnectionUrlBuilders
Class Method Summary
collapse
-
.env_exports_for_databases(databases_hash, shard_index:) ⇒ Object
-
.extract_db_name(url) ⇒ Object
-
.postgres_url_for_database_name(databases_hash, database_name) ⇒ Object
-
.postgres_url_for_shard(databases_hash, shard_index:, connection: nil) ⇒ Object
-
.postgres_url_for_template(databases_hash) ⇒ Object
-
.shard_database_name(databases_hash, shard_index:, connection: nil) ⇒ Object
-
.shard_database_plan(databases_hash, shard_index:) ⇒ Object
-
.template_database_name_for(databases_hash, connection: nil) ⇒ Object
-
.template_prepare_env(databases_hash) ⇒ Object
ENV overrides so bin/rails db:prepare runs once for multi-DB apps: each connection keeps its own migrations_paths (e.g. db/cache_migrate) instead of pointing DATABASE_URL at every template in turn.
-
.template_prepare_env_fill_connections!(dh, primary_template, out) ⇒ Object
-
.template_prepare_env_shell_log(databases_hash) ⇒ Object
-
.unique_template_migrate_urls(databases_hash) ⇒ Object
-
.url_for_database_name(databases_hash, database_name) ⇒ Object
-
.url_for_shard(databases_hash, shard_index:, connection: nil) ⇒ Object
-
.url_for_template(databases_hash) ⇒ Object
Class Method Details
.env_exports_for_databases(databases_hash, shard_index:) ⇒ Object
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
# File 'lib/polyrun/database/url_builder.rb', line 128
def env_exports_for_databases(databases_hash, shard_index:)
dh = databases_hash.is_a?(Hash) ? databases_hash : {}
out = {}
primary_url = url_for_shard(dh, shard_index: shard_index)
out["DATABASE_URL"] = primary_url
out["TEST_DB_NAME"] = (primary_url)
conns = dh["connections"] || dh[:connections] || []
Array(conns).each do |c|
name = (c["name"] || c[:name]).to_s
next if name.empty?
u = url_for_shard(dh, shard_index: shard_index, connection: name)
key = (c["env_key"] || c[:env_key]).to_s.strip
key = "DATABASE_URL_#{name.upcase.tr("-", "_")}" if key.empty?
out[key] = u
end
out
end
|
148
149
150
151
152
153
154
155
|
# File 'lib/polyrun/database/url_builder.rb', line 148
def (url)
s = url.to_s
return s.sub(/\Asqlite3:/i, "") if s.match?(/\Asqlite3:/i)
URI.parse(s).path.delete_prefix("/").split("?", 2).first
rescue URI::InvalidURIError
nil
end
|
.postgres_url_for_database_name(databases_hash, database_name) ⇒ Object
17
18
19
|
# File 'lib/polyrun/database/url_builder.rb', line 17
def postgres_url_for_database_name(databases_hash, database_name)
url_for_database_name(databases_hash, database_name)
end
|
.postgres_url_for_shard(databases_hash, shard_index:, connection: nil) ⇒ Object
21
22
23
|
# File 'lib/polyrun/database/url_builder.rb', line 21
def postgres_url_for_shard(databases_hash, shard_index:, connection: nil)
url_for_shard(databases_hash, shard_index: shard_index, connection: connection)
end
|
.postgres_url_for_template(databases_hash) ⇒ Object
13
14
15
|
# File 'lib/polyrun/database/url_builder.rb', line 13
def postgres_url_for_template(databases_hash)
url_for_template(databases_hash)
end
|
.shard_database_name(databases_hash, shard_index:, connection: nil) ⇒ Object
75
76
77
|
# File 'lib/polyrun/database/url_builder.rb', line 75
def shard_database_name(databases_hash, shard_index:, connection: nil)
(url_for_shard(databases_hash, shard_index: shard_index, connection: connection))
end
|
.shard_database_plan(databases_hash, shard_index:) ⇒ Object
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/polyrun/database/url_builder.rb', line 91
def shard_database_plan(databases_hash, shard_index:)
dh = databases_hash.is_a?(Hash) ? databases_hash : {}
rows = []
primary_shard = shard_database_name(dh, shard_index: shard_index, connection: nil)
primary_tmpl = template_database_name_for(dh, connection: nil)
if !primary_shard.empty? && !primary_tmpl.empty?
rows << {new_db: primary_shard, template_db: primary_tmpl}
end
Array(dh["connections"] || dh[:connections]).each do |c|
nm = (c["name"] || c[:name]).to_s
next if nm.empty?
sname = shard_database_name(dh, shard_index: shard_index, connection: nm)
tname = template_database_name_for(dh, connection: nm)
rows << {new_db: sname, template_db: tname} if !sname.empty? && !tname.empty?
end
rows
end
|
.template_database_name_for(databases_hash, connection: nil) ⇒ Object
79
80
81
82
83
84
85
86
87
88
89
|
# File 'lib/polyrun/database/url_builder.rb', line 79
def template_database_name_for(databases_hash, connection: nil)
dh = databases_hash.is_a?(Hash) ? databases_hash : {}
if connection.nil?
return (dh["template_db"] || dh[:template_db]).to_s
end
c = Array(dh["connections"] || dh[:connections]).find { |x| (x["name"] || x[:name]).to_s == connection.to_s }
return "" unless c
(c["template_db"] || c[:template_db] || dh["template_db"] || dh[:template_db]).to_s
end
|
.template_prepare_env(databases_hash) ⇒ Object
ENV overrides so bin/rails db:prepare runs once for multi-DB apps: each connection keeps its own migrations_paths (e.g. db/cache_migrate) instead of pointing DATABASE_URL at every template in turn.
40
41
42
43
44
45
46
47
48
|
# File 'lib/polyrun/database/url_builder.rb', line 40
def template_prepare_env(databases_hash)
dh = databases_hash.is_a?(Hash) ? databases_hash : {}
pt = (dh["template_db"] || dh[:template_db]).to_s
raise Polyrun::Error, "template_prepare_env: set databases.template_db" if pt.empty?
out = {}
out["DATABASE_URL"] = url_for_database_name(dh, pt)
template_prepare_env_fill_connections!(dh, pt, out)
end
|
.template_prepare_env_fill_connections!(dh, primary_template, out) ⇒ Object
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# File 'lib/polyrun/database/url_builder/template_prepare.rb', line 6
def template_prepare_env_fill_connections!(dh, primary_template, out)
Array(dh["connections"] || dh[:connections]).each do |c|
nm = (c["name"] || c[:name]).to_s
key = (c["env_key"] || c[:env_key]).to_s.strip
key = "DATABASE_URL_#{nm.upcase.tr("-", "_")}" if key.empty? && !nm.empty?
next if key.empty?
tname = (c["template_db"] || c[:template_db]).to_s
tname = primary_template if tname.empty?
out[key] = url_for_database_name(dh, tname)
end
out
end
|
.template_prepare_env_shell_log(databases_hash) ⇒ Object
50
51
52
|
# File 'lib/polyrun/database/url_builder.rb', line 50
def template_prepare_env_shell_log(databases_hash)
template_prepare_env(databases_hash).sort.map { |k, v| "#{k}=#{Shellwords.escape(v.to_s)}" }.join(" ")
end
|
.unique_template_migrate_urls(databases_hash) ⇒ Object
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
# File 'lib/polyrun/database/url_builder.rb', line 54
def unique_template_migrate_urls(databases_hash)
dh = databases_hash.is_a?(Hash) ? databases_hash : {}
seen = {}
out = []
pt = (dh["template_db"] || dh[:template_db]).to_s
unless pt.empty?
out << url_for_database_name(dh, pt)
seen[pt] = true
end
Array(dh["connections"] || dh[:connections]).each do |c|
t = (c["template_db"] || c[:template_db]).to_s
t = pt if t.empty?
next if t.empty?
next if seen[t]
out << url_for_database_name(dh, t)
seen[t] = true
end
out
end
|
.url_for_database_name(databases_hash, database_name) ⇒ Object
.url_for_shard(databases_hash, shard_index:, connection: nil) ⇒ Object
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/polyrun/database/url_builder.rb', line 111
def url_for_shard(databases_hash, shard_index:, connection: nil)
dh = databases_hash.is_a?(Hash) ? databases_hash : {}
conn = Connection.resolve_connection(dh)
pattern =
if connection
conns = dh["connections"] || dh[:connections] || []
c = Array(conns).find { |x| (x["name"] || x[:name]).to_s == connection.to_s }
(c && (c["shard_db_pattern"] || c[:shard_db_pattern])) || dh["shard_db_pattern"]
else
dh["shard_db_pattern"] || dh[:shard_db_pattern]
end
pattern ||= "app_test_%{shard}"
dbname = pattern.to_s.gsub("%{shard}", Integer(shard_index).to_s).gsub("%<shard>d", format("%d", Integer(shard_index)))
Connection.build_database_url(dbname, conn)
end
|
.url_for_template(databases_hash) ⇒ Object
25
26
27
28
29
30
31
|
# File 'lib/polyrun/database/url_builder.rb', line 25
def url_for_template(databases_hash)
dh = databases_hash.is_a?(Hash) ? databases_hash : {}
dbname = dh["template_db"] || dh[:template_db]
raise Polyrun::Error, "databases.template_db is required" if dbname.nil? || dbname.to_s.empty?
url_for_database_name(dh, dbname.to_s)
end
|