exwiw 0.4.6 → 0.4.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dac24d68af7c0c39949a11c810cccc14e6818ac0edb9198a3a6b846d2d81bcee
4
- data.tar.gz: c4b111dc3dccc8940627b7dcabf2ea5633300eb5e670b52ec8683e78a2922040
3
+ metadata.gz: 6bf23b63e169e4f28dceda8611fe1dc599ed3fba7565a063ac11d7e66e84816e
4
+ data.tar.gz: 4768cb5990bc6bb534e38bf458d814ad7be4ff57cc4ecb02565aae245078a7d1
5
5
  SHA512:
6
- metadata.gz: 15cdaa9351b32c3159f27a79204506f557825441d2c8253da5981d0e903504240963fcf279a34c28b02f084004f9d728499ee8fb3ea609a94b3583b72f8b8ce8
7
- data.tar.gz: 7b7de3276484ce8bb97164f26aed9dc23f25f51736065c0f3f15337be49f82db322bbe16534fc77c0ad85fefd55fa1e825b25933b8c2f0e85e50694da6333f2f
6
+ metadata.gz: bd2b11ab17de73e205639bc917cdd4bff23a793caa282c23f1a987b3391a6bc1550e65078924f82c6e63bdc03c22a9e37b0b1977c2602f5fbe0940b68dd92c13
7
+ data.tar.gz: 78681a8c80263454d9bcaef29282de2bf1853b478dd2025382b2a0e4dfe089ea14af8dd970cd0127c8ddf2b71f9a3306024959303052102592203487d387e5a7
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.4.7] - 2026-06-10
6
+
7
+ ### Fixed
8
+
9
+ - PostgreSQL: `CREATE TYPE ... AS ENUM` statements in schema dumps no longer duplicate labels when the same enum type is used by multiple columns across the target tables. The `query_enum_types` query now filters by column in a subquery so the `pg_type` / `pg_enum` join produces each label exactly once.
10
+
11
+ ### Added
12
+
13
+ - MongoDB: a `belongs_to` may now declare `references`, the parent field its foreign key actually points at, so foreign-key propagation can follow a relation that references a non-`_id` parent field (e.g. a `uuid`). Previously the adapter always stashed the parent's `primary_key` (`_id`, an ObjectId) and constrained children with `foreign_key $in [ObjectId(...)]`; a child whose FK stores the parent's `uuid` String never matched, so its slice (and everything below it) came back empty — making business-entity-scoped dumps unusable for models referenced by `primary_key: :uuid`. With `"references": "uuid"` on the child's `belongs_to`, the adapter captures the parent's `uuid` values during extraction and matches the child against those instead. `references` defaults to the parent's `primary_key` (so existing configs are unchanged). `schema:generate_mongoid` now auto-emits it by reading Mongoid's `belongs_to ..., primary_key:` (a non-`_id` primary key becomes `"references": "<field>"`; a default `_id` emits nothing), so no hand-editing is needed for `primary_key:`-declared associations — and a hand-added value still survives regeneration. The SQL adapters ignore it (they join on the parent primary key).
14
+ - MongoDB: `--uri=URI` connects with a full connection string (`mongodb://...` or `mongodb+srv://...`), letting you reach managed/replica-set deployments (e.g. Atlas) where TLS, `replicaSet`, `authSource`, and credentials must be specified — they live in the URI's query string. Previously the adapter was hard-coded to a single `host:port` with no TLS / `authSource` / `replicaSet` / SRV support, so such instances were unreachable. When given, the URI is the source of truth: `--host`/`--port`/`--user`/`DATABASE_PASSWORD` are ignored and `--host`/`--port`/`--database` are no longer required; `--database`, if still passed, overrides the database in the URI path. The flag is mongodb-only, and the URI is never written to logs (it may carry credentials).
15
+
5
16
  ## [0.4.6] - 2026-06-08
6
17
 
7
18
  ### Fixed
data/README.md CHANGED
@@ -494,6 +494,7 @@ The MongoDB adapter is experimental. To use it:
494
494
 
495
495
  - Add `gem "mongo"` to your Gemfile in addition to `exwiw` (it is not declared as a runtime dependency of the gem).
496
496
  - Set `--adapter=mongodb`. `--user` / `DATABASE_PASSWORD` are optional and only needed when your MongoDB requires authentication.
497
+ - `--uri=URI` connects with a full MongoDB connection string (`mongodb://...` or `mongodb+srv://...`) instead of `--host`/`--port`. Use it for managed/replica-set deployments (e.g. Atlas) where TLS, `replicaSet`, `authSource`, and credentials must be expressed — put them in the URI's query string (e.g. `mongodb+srv://user:pass@cluster.example.com/?authSource=admin&tls=true`). The URI takes precedence: when given, `--host`/`--port`/`--user`/`DATABASE_PASSWORD` are ignored, and `--host`/`--port`/`--database` are no longer required on the CLI. `--database`, if still passed, overrides the database in the URI path; otherwise the database from the URI is used. This flag is **mongodb-only** (the SQL adapters shell out to their own client binaries and have no equivalent). The URI may carry credentials, so it is never written to logs.
497
498
  - The MongoDB adapter consumes a separate config type, `MongodbCollectionConfig`, with MongoDB-native naming. Use `fields` (instead of the SQL adapters' `columns`), and set `"primary_key": "_id"`. Foreign keys (`shop_id`, `user_id`, ...) stay as ordinary fields.
498
499
  - `--ids` values are coerced to the type actually stored in `_id` before filtering: integer-looking ids become `Integer`, 24-char hex ids become `BSON::ObjectId` (Mongoid's default `_id` type — a plain String would never match an ObjectId), and any other string is left as-is.
499
500
  - `--target-collection=COLLECTION` is a mongodb-only alias of `--target-table` (use whichever reads better for MongoDB). Specifying both, or using `--target-collection` with a non-mongodb adapter, is an error.
@@ -45,13 +45,20 @@ module Exwiw
45
45
  # the same config.
46
46
  @embedded_children_by_parent = index_embedded_children(config_by_name)
47
47
 
48
+ # Which of this collection's fields downstream children will `$in`-match
49
+ # against (always including primary_key). Stashed for the matching
50
+ # #execute call to capture, by the same build_query-before-execute
51
+ # invariant the embedded index relies on.
52
+ @propagation_keys = propagation_keys_for(config, config_by_name)
53
+
48
54
  filter =
49
55
  if config.name == dump_target.table_name
50
56
  # `--ids-field` may override which field --ids is matched against;
51
57
  # otherwise fall back to the primary key. Note this only changes the
52
58
  # WHERE filter on the target collection — downstream foreign-key
53
- # propagation still keys off `primary_key` (see #execute, which
54
- # stashes doc[primary_key] into @state).
59
+ # propagation keys off each child belongs_to's `references` field
60
+ # (default: the parent primary_key); see #execute, which stashes
61
+ # those fields into @state.
55
62
  #
56
63
  # Type coercion is only applied to the primary key (`_id`), whose
57
64
  # stored type we know (Mongoid's default ObjectId). For a custom
@@ -64,16 +71,15 @@ module Exwiw
64
71
  { config.primary_key => { "$in" => coerce_ids(dump_target.ids) } }
65
72
  end
66
73
  else
67
- constrained = config.belongs_tos.select do |relation|
68
- @state.key?(relation.table_name) && !@state[relation.table_name].empty?
69
- end
70
-
71
- if constrained.empty?
72
- {}
73
- else
74
- constrained.each_with_object({}) do |relation, acc|
75
- acc[relation.foreign_key] = { "$in" => @state[relation.table_name] }
76
- end
74
+ config.belongs_tos.each_with_object({}) do |relation, acc|
75
+ # Constrain by the parent field this FK actually references
76
+ # (`relation.references`, default the parent primary_key). The
77
+ # values were captured from that field's documents in #execute, so
78
+ # their BSON type already matches the stored FK — no coercion.
79
+ values = parent_state_for(relation, config_by_name)
80
+ next if values.nil? || values.empty?
81
+
82
+ acc[relation.foreign_key] = { "$in" => values }
77
83
  end
78
84
  end
79
85
 
@@ -81,7 +87,7 @@ module Exwiw
81
87
  collection: config.name,
82
88
  primary_key: config.primary_key,
83
89
  filter: filter,
84
- projection: build_projection(config),
90
+ projection: build_projection(config, @propagation_keys),
85
91
  )
86
92
  end
87
93
 
@@ -94,7 +100,14 @@ module Exwiw
94
100
  .comment(query_comment_text("collection=#{query.collection}"))
95
101
  .to_a
96
102
 
97
- @state[query.collection] = docs.map { |doc| doc[query.primary_key] }
103
+ # Stash, per referenced field, the values children will `$in`-match
104
+ # against. @propagation_keys is set by the build_query call for this same
105
+ # collection; fall back to the primary key if execute is driven without a
106
+ # preceding build_query (e.g. in isolation from a test).
107
+ keys = @propagation_keys || [query.primary_key]
108
+ @state[query.collection] = keys.each_with_object({}) do |key, acc|
109
+ acc[key] = docs.map { |doc| doc[key] }
110
+ end
98
111
 
99
112
  docs
100
113
  end
@@ -227,7 +240,7 @@ module Exwiw
227
240
  end
228
241
  end
229
242
 
230
- private def build_projection(config)
243
+ private def build_projection(config, propagation_keys = [config.primary_key])
231
244
  projection = {}
232
245
  # Always include primary key so masking templates referencing it work,
233
246
  # even if it is not declared in fields.
@@ -240,9 +253,40 @@ module Exwiw
240
253
  embedded_children_of(config).each do |child|
241
254
  projection[child.embedded_in.path] = 1
242
255
  end
256
+ # Ensure every field a child references is fetched, even one not declared
257
+ # in `fields` — otherwise doc[ref] would be nil and the child's $in empty.
258
+ propagation_keys.each { |key| projection[key] = 1 }
243
259
  projection
244
260
  end
245
261
 
262
+ # The distinct set of this collection's fields that downstream children
263
+ # constrain on (each child belongs_to's `references`, defaulting to this
264
+ # collection's primary_key), with primary_key always included so the
265
+ # historical primary-key-keyed propagation keeps working.
266
+ private def propagation_keys_for(config, config_by_name)
267
+ referenced = config_by_name.each_value.flat_map do |child|
268
+ next [] if child.embedded?
269
+
270
+ child.belongs_tos
271
+ .select { |relation| relation.table_name == config.name }
272
+ .map { |relation| relation.references || config.primary_key }
273
+ end
274
+ ([config.primary_key] + referenced).uniq
275
+ end
276
+
277
+ # The captured parent-collection values a child belongs_to should be
278
+ # constrained by: the values of the parent field the FK references
279
+ # (`relation.references`, default the parent primary_key). nil when the
280
+ # parent has not been executed yet.
281
+ private def parent_state_for(relation, config_by_name)
282
+ parent_fields = @state[relation.table_name]
283
+ return nil if parent_fields.nil?
284
+
285
+ reference_field =
286
+ relation.references || config_by_name.fetch(relation.table_name).primary_key
287
+ parent_fields[reference_field]
288
+ end
289
+
246
290
  private def apply_replace_with!(doc, config)
247
291
  config.fields.each do |field|
248
292
  next unless field.replace_with
@@ -292,16 +336,34 @@ module Exwiw
292
336
  @db ||=
293
337
  begin
294
338
  require 'mongo'
295
- address = "#{@connection_config.host}:#{@connection_config.port}"
296
- options = { database: @connection_config.database_name }
297
- if @connection_config.user && !@connection_config.user.to_s.empty?
298
- options[:user] = @connection_config.user
299
- options[:password] = @connection_config.password
300
- end
301
339
  Mongo::Logger.logger.level = ::Logger::WARN
302
- Mongo::Client.new([address], **options)
340
+ if uri_connection?
341
+ # A full connection URI (e.g. `mongodb+srv://...`) is the source of
342
+ # truth: TLS, replicaSet, authSource and credentials are read from
343
+ # it, so host/port/user/password are ignored. `--database`, if
344
+ # given, overrides the database in the URI path; otherwise the
345
+ # URI's own database is used. The URI is never logged (it may carry
346
+ # credentials).
347
+ client_options = {}
348
+ if @connection_config.database_name && !@connection_config.database_name.to_s.empty?
349
+ client_options[:database] = @connection_config.database_name
350
+ end
351
+ Mongo::Client.new(@connection_config.uri, **client_options)
352
+ else
353
+ address = "#{@connection_config.host}:#{@connection_config.port}"
354
+ options = { database: @connection_config.database_name }
355
+ if @connection_config.user && !@connection_config.user.to_s.empty?
356
+ options[:user] = @connection_config.user
357
+ options[:password] = @connection_config.password
358
+ end
359
+ Mongo::Client.new([address], **options)
360
+ end
303
361
  end
304
362
  end
363
+
364
+ private def uri_connection?
365
+ !@connection_config.uri.nil? && !@connection_config.uri.to_s.empty?
366
+ end
305
367
  end
306
368
  end
307
369
  end
@@ -373,20 +373,22 @@ module Exwiw
373
373
 
374
374
  placeholders = table_names.each_with_index.map { |_, i| "$#{i + 1}" }.join(', ')
375
375
  sql = <<~SQL
376
- SELECT DISTINCT
376
+ SELECT
377
377
  n.nspname AS type_schema,
378
378
  t.typname AS type_name,
379
379
  array_agg(e.enumlabel ORDER BY e.enumsortorder) AS enum_labels
380
- FROM pg_attribute a
381
- JOIN pg_class c ON c.oid = a.attrelid
382
- JOIN pg_namespace cn ON cn.oid = c.relnamespace
383
- JOIN pg_type t ON t.oid = a.atttypid
384
- JOIN pg_namespace n ON n.oid = t.typnamespace
385
- JOIN pg_enum e ON e.enumtypid = t.oid
386
- WHERE c.relname IN (#{placeholders})
387
- AND a.attnum > 0
388
- AND NOT a.attisdropped
389
- AND t.typtype = 'e'
380
+ FROM pg_type t
381
+ JOIN pg_namespace n ON n.oid = t.typnamespace
382
+ JOIN pg_enum e ON e.enumtypid = t.oid
383
+ WHERE t.typtype = 'e'
384
+ AND t.oid IN (
385
+ SELECT a.atttypid
386
+ FROM pg_attribute a
387
+ JOIN pg_class c ON c.oid = a.attrelid
388
+ WHERE c.relname IN (#{placeholders})
389
+ AND a.attnum > 0
390
+ AND NOT a.attisdropped
391
+ )
390
392
  GROUP BY n.nspname, t.typname
391
393
  ORDER BY n.nspname, t.typname
392
394
  SQL
@@ -12,6 +12,20 @@ module Exwiw
12
12
  # non-polymorphic belongs_to.
13
13
  attribute :foreign_type, optional(String), skip_serializing_if_nil: true
14
14
  attribute :type_value, optional(String), skip_serializing_if_nil: true
15
+ # The field on the parent (`table_name`) that `foreign_key` actually points
16
+ # at. nil means the parent's `primary_key` (the usual `_id`), so existing
17
+ # configs behave exactly as before. Set it when the FK references a non-`_id`
18
+ # parent field — e.g. Mongoid's `belongs_to :foo, primary_key: :uuid`, where
19
+ # the child stores `foo.uuid` rather than `foo._id`.
20
+ #
21
+ # Only the MongodbAdapter consumes this (to stash and `$in`-match the right
22
+ # parent field during foreign-key propagation); the SQL adapters ignore it,
23
+ # since they join on the parent primary key. MongoidSchemaGenerator emits it
24
+ # automatically from Mongoid's `belongs_to ..., primary_key:` (only when that
25
+ # is non-`_id`); a value may also be hand-added, and either way it survives
26
+ # regeneration (see TableConfig#merge / MongodbCollectionConfig#merge), so a
27
+ # hand edit is not clobbered by re-introspection.
28
+ attribute :references, optional(String), skip_serializing_if_nil: true
15
29
  # User-owned fields. The schema generators never emit them, but a user can
16
30
  # add them by hand and they survive regeneration (see TableConfig#merge /
17
31
  # MongodbCollectionConfig#merge). `ignore:true` drops the relation from
@@ -28,8 +42,10 @@ module Exwiw
28
42
  end
29
43
 
30
44
  # Structural identity used to match a freshly generated belongs_to against a
31
- # user-maintained one during merge. `comment`/`ignore` are user-owned and so
32
- # are intentionally excluded.
45
+ # user-maintained one during merge. `comment`/`ignore`/`references` are
46
+ # intentionally excluded so a generated relation matches a hand-edited one
47
+ # regardless of whether either carries a `references`, letting the merge
48
+ # reconcile them (a hand-edited `references` wins over the generated one).
33
49
  def identity
34
50
  [table_name, foreign_key, foreign_type, type_value]
35
51
  end
data/lib/exwiw/cli.rb CHANGED
@@ -32,6 +32,7 @@ module Exwiw
32
32
  @database_port = nil
33
33
  @database_user = nil
34
34
  @database_password = ENV["DATABASE_PASSWORD"]
35
+ @connection_uri = nil
35
36
  @output_dir = nil
36
37
  @config_dir = nil
37
38
  @database_adapter = nil
@@ -64,6 +65,7 @@ module Exwiw
64
65
  user: @database_user,
65
66
  password: @database_password,
66
67
  database_name: @database_name,
68
+ uri: @connection_uri,
67
69
  )
68
70
 
69
71
  dump_target = DumpTarget.new(
@@ -115,17 +117,21 @@ module Exwiw
115
117
 
116
118
  resolve_target_collection_alias!
117
119
  resolve_ids_column_alias!
120
+ resolve_uri_option!
118
121
 
119
122
  if @subcommand == "explain"
120
123
  validate_explain_only!
121
124
  end
122
125
 
123
126
  if @database_adapter != "sqlite"
124
- required_options = {
125
- "Target database host" => @database_host,
126
- "Target database port" => @database_port,
127
- "Target database name" => @database_name,
128
- }
127
+ # When a connection URI is supplied (mongodb only), host/port/database
128
+ # are read from the URI, so none of them are required on the CLI.
129
+ required_options = {}
130
+ unless @connection_uri
131
+ required_options["Target database host"] = @database_host
132
+ required_options["Target database port"] = @database_port
133
+ required_options["Target database name"] = @database_name
134
+ end
129
135
  required_options["Database user"] = @database_user unless @database_adapter == "mongodb"
130
136
  required_options.each do |k, v|
131
137
  if v.nil?
@@ -253,6 +259,19 @@ module Exwiw
253
259
  end
254
260
  end
255
261
 
262
+ # `--uri` supplies a full connection string (e.g. `mongodb+srv://...`) and is
263
+ # mongodb-only — the SQL adapters shell out to their own client binaries with
264
+ # discrete host/port/user flags and have no equivalent. Runs after the
265
+ # adapter name has been normalized so the family check is reliable.
266
+ private def resolve_uri_option!
267
+ return if @connection_uri.nil?
268
+
269
+ if @database_adapter != "mongodb"
270
+ $stderr.puts "--uri is only supported by the mongodb adapter (use --host/--port)"
271
+ exit 1
272
+ end
273
+ end
274
+
256
275
  private def validate_explain_only!
257
276
  if @database_adapter == "mongodb"
258
277
  $stderr.puts "mongodb adapter is not yet supported by 'explain' subcommand"
@@ -354,6 +373,7 @@ module Exwiw
354
373
  @config_dir = File.expand_path(v)
355
374
  end
356
375
  opts.on("-a", "--adapter=ADAPTER", "Database adapter: mysql, sqlite, postgresql, mongodb (aliases: mysql2, sqlite3)") { |v| @database_adapter = v }
376
+ opts.on("--uri=URI", "Full MongoDB connection URI (mongodb:// or mongodb+srv://). mongodb adapter only; takes precedence over --host/--port/--user. TLS, replicaSet, authSource and credentials are read from the URI.") { |v| @connection_uri = v }
357
377
  opts.on("--database=DATABASE", "Target database name") { |v| @database_name = v }
358
378
  opts.on("--target-table=[TABLE]", "Target table for extraction. If omitted, dump all tables.") { |v| @target_table_name = v }
359
379
  opts.on("--target-collection=[COLLECTION]", "Alias of --target-table for the mongodb adapter.") { |v| @target_collection_name = v }
@@ -75,14 +75,16 @@ module Exwiw
75
75
  merged.embedded_in = passed.embedded_in
76
76
 
77
77
  # Structural facts of each belongs_to come from the freshly generated
78
- # config, but the user-owned `comment`/`ignore` carry over when the same
79
- # relation still exists.
78
+ # config (including a generator-derived `references`), but the user-owned
79
+ # `comment`/`ignore` and a hand-edited `references`, which overrides the
80
+ # generated one — carry over when the same relation still exists.
80
81
  receiver_belongs_to_by_identity = belongs_tos.each_with_object({}) { |bt, h| h[bt.identity] = bt }
81
82
  merged.belongs_tos = passed.belongs_tos.map do |pbt|
82
83
  receiver_bt = receiver_belongs_to_by_identity[pbt.identity]
83
84
  if receiver_bt
84
85
  pbt.comment = receiver_bt.comment if receiver_bt.comment
85
86
  pbt.ignore = receiver_bt.ignore unless receiver_bt.ignore.nil?
87
+ pbt.references = receiver_bt.references if receiver_bt.references
86
88
  end
87
89
  pbt
88
90
  end
@@ -220,14 +220,24 @@ module Exwiw
220
220
  .uniq
221
221
  end
222
222
 
223
- # Resolves a referenced belongs_to to a `{ table_name, foreign_key }` pair.
223
+ # Resolves a referenced belongs_to to a `{ table_name, foreign_key }` pair
224
+ # (plus `references` when the FK points at a non-`_id` parent field).
224
225
  # `assoc.klass` raises NameError when the association's target class no longer
225
226
  # exists (a stale/legacy `belongs_to`, e.g. pointing at a model removed years
226
227
  # ago). Under `skip_unsupported` such a relation is skipped with a warning —
227
228
  # its foreign-key column is still tracked as an ordinary field by
228
229
  # `aggregate_fields`, mirroring how polymorphic / HABTM relations are dropped.
229
230
  private def belongs_to_for(assoc)
230
- { table_name: assoc.klass.collection_name.to_s, foreign_key: assoc.foreign_key }
231
+ result = { table_name: assoc.klass.collection_name.to_s, foreign_key: assoc.foreign_key }
232
+ # Mongoid's `belongs_to ..., primary_key: :uuid` makes the child's foreign
233
+ # key reference that parent field rather than the parent's `_id`. Surface
234
+ # it as `references` so MongodbAdapter constrains children by the right
235
+ # field (issue B1). Omit it for the default `_id` (the parent primary_key
236
+ # the generator emits) so existing configs/snapshots are unchanged. SQL
237
+ # adapters ignore `references`; only MongodbAdapter consumes it.
238
+ reference_field = assoc.primary_key.to_s
239
+ result[:references] = reference_field unless reference_field == "_id"
240
+ result
231
241
  rescue NameError, ::Mongoid::Errors::MongoidError => e
232
242
  raise e unless @skip_unsupported
233
243
 
@@ -139,8 +139,10 @@ module Exwiw
139
139
  merged_table.ignore = ignore
140
140
 
141
141
  # Structural facts of each belongs_to come from the freshly generated
142
- # config, but the user-owned `comment`/`ignore` carry over when the same
143
- # relation still exists.
142
+ # config, but the user-owned `comment`/`ignore`/`references` carry over
143
+ # when the same relation still exists. (`references` is only consumed by
144
+ # the MongodbAdapter, but it lives on the shared BelongsTo, so preserve
145
+ # it here too rather than silently dropping a hand-added value.)
144
146
  receiver_belongs_to_by_identity = belongs_tos.each_with_object({}) { |bt, hash| hash[bt.identity] = bt }
145
147
  merged_table.belongs_tos =
146
148
  passed_table.belongs_tos.map do |passed_belongs_to|
@@ -148,6 +150,7 @@ module Exwiw
148
150
  if receiver_belongs_to
149
151
  passed_belongs_to.comment = receiver_belongs_to.comment if receiver_belongs_to.comment
150
152
  passed_belongs_to.ignore = receiver_belongs_to.ignore unless receiver_belongs_to.ignore.nil?
153
+ passed_belongs_to.references = receiver_belongs_to.references if receiver_belongs_to.references
151
154
  end
152
155
  passed_belongs_to
153
156
  end
data/lib/exwiw/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Exwiw
4
- VERSION = "0.4.6"
4
+ VERSION = "0.4.7"
5
5
  end
data/lib/exwiw.rb CHANGED
@@ -40,5 +40,9 @@ module Exwiw
40
40
  # the target table. When nil the table's primary key is used (the historical
41
41
  # behavior). Currently only honored by the mongodb adapter.
42
42
  DumpTarget = Struct.new(:table_name, :ids, :ids_field, keyword_init: true)
43
- ConnectionConfig = Struct.new(:adapter, :host, :port, :user, :password, :database_name, keyword_init: true)
43
+ # `uri` is an optional full connection string (currently only honored by the
44
+ # mongodb adapter, e.g. `mongodb+srv://...`). When present it is the source of
45
+ # truth for the connection — host/port/user/password are ignored — so TLS,
46
+ # replica_set, auth_source, etc. can be expressed via the URI's query string.
47
+ ConnectionConfig = Struct.new(:adapter, :host, :port, :user, :password, :database_name, :uri, keyword_init: true)
44
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exwiw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shia