Skip to content

Commit 1cb7930

Browse files
committed
refactor(catalog): drop unused scryfall_printing_search FTS table
Search never queried the FTS5 table; it only cost disk space and a full rebuild on every Scryfall catalog import. Remove the table, its import row generation, and its backup entry. The migration is reversible and repopulates the table from printings and cards on rollback.
1 parent 5c0eb42 commit 1cb7930

7 files changed

Lines changed: 70 additions & 154 deletions

File tree

‎lib/manavault/backup.ex‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ defmodule Manavault.Backup do
1313
@manifest_name "manifest.json"
1414
@default_local_paths []
1515
@catalog_tables ~w(
16-
scryfall_printing_search
1716
scryfall_syncs
1817
scryfall_printings
1918
scryfall_cards

‎lib/manavault/catalog/scryfall/import.ex‎

Lines changed: 2 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ defmodule Manavault.Catalog.Scryfall.Import do
120120
fn ->
121121
insert_card_rows(rows.cards, replace_oracle_tag_fields?)
122122
insert_printing_rows(rows.printings)
123-
refresh_printing_search_rows(rows.search_rows)
124123
{:ok, :imported}
125124
end,
126125
timeout: :infinity
@@ -132,7 +131,6 @@ defmodule Manavault.Catalog.Scryfall.Import do
132131
source_count: 0,
133132
cards_count: 0,
134133
printings_count: 0,
135-
search_rows_count: 0,
136134
next_progress: @progress_source_card_interval
137135
}
138136
end
@@ -142,8 +140,7 @@ defmodule Manavault.Catalog.Scryfall.Import do
142140
counts
143141
| source_count: counts.source_count + source_count,
144142
cards_count: counts.cards_count + length(rows.cards),
145-
printings_count: counts.printings_count + length(rows.printings),
146-
search_rows_count: counts.search_rows_count + length(rows.search_rows)
143+
printings_count: counts.printings_count + length(rows.printings)
147144
}
148145
end
149146

@@ -212,8 +209,7 @@ defmodule Manavault.Catalog.Scryfall.Import do
212209
when processed >= next or processed == source_count do
213210
Logger.info(
214211
"Scryfall catalog import progress source_cards=#{processed}/#{source_count} " <>
215-
"cards=#{counts.cards_count} printings=#{counts.printings_count} " <>
216-
"search_rows=#{counts.search_rows_count}"
212+
"cards=#{counts.cards_count} printings=#{counts.printings_count}"
217213
)
218214

219215
%{counts | next_progress: next_progress_after(processed)}
@@ -254,67 +250,6 @@ defmodule Manavault.Catalog.Scryfall.Import do
254250
|> Enum.each(fn batch -> Repo.insert_all(schema, batch, opts) end)
255251
end
256252

257-
defp refresh_printing_search_rows([]), do: :ok
258-
259-
defp refresh_printing_search_rows(rows) do
260-
rows
261-
|> Enum.map(& &1.scryfall_id)
262-
|> Enum.chunk_every(@batch_size)
263-
|> Enum.each(fn ids ->
264-
placeholders = Enum.map_join(ids, ",", fn _ -> "?" end)
265-
266-
Repo.query!(
267-
"DELETE FROM scryfall_printing_search WHERE scryfall_id IN (#{placeholders})",
268-
ids
269-
)
270-
end)
271-
272-
rows
273-
|> Enum.chunk_every(@batch_size)
274-
|> Enum.each(fn batch ->
275-
values = Enum.map_join(batch, ",", fn _ -> "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" end)
276-
277-
params =
278-
Enum.flat_map(batch, fn row ->
279-
[
280-
row.scryfall_id,
281-
row.name,
282-
row.compact_name,
283-
row.flavor_name,
284-
row.compact_flavor_name,
285-
row.flavor_text,
286-
row.compact_flavor_text,
287-
row.type_line,
288-
row.oracle_text,
289-
row.compact_oracle_text,
290-
row.set_code,
291-
row.collector_number
292-
]
293-
end)
294-
295-
Repo.query!(
296-
"""
297-
INSERT INTO scryfall_printing_search (
298-
scryfall_id,
299-
name,
300-
compact_name,
301-
flavor_name,
302-
compact_flavor_name,
303-
flavor_text,
304-
compact_flavor_text,
305-
type_line,
306-
oracle_text,
307-
compact_oracle_text,
308-
set_code,
309-
collector_number
310-
)
311-
VALUES #{values}
312-
""",
313-
params
314-
)
315-
end)
316-
end
317-
318253
defp maybe_reconcile_printings(false, _imported_at), do: :ok
319254

320255
defp maybe_reconcile_printings(true, imported_at) do
@@ -410,8 +345,6 @@ defmodule Manavault.Catalog.Scryfall.Import do
410345
|> Enum.chunk_every(@batch_size)
411346
|> Enum.each(&clear_trade_wants/1)
412347

413-
delete_printing_search_rows(stale_ids)
414-
415348
Enum.each(Enum.chunk_every(stale_ids, @batch_size), fn ids ->
416349
Repo.delete_all(from printing in Printing, where: printing.scryfall_id in ^ids)
417350
end)
@@ -541,19 +474,6 @@ defmodule Manavault.Catalog.Scryfall.Import do
541474
end)
542475
end
543476

544-
defp delete_printing_search_rows([]), do: :ok
545-
546-
defp delete_printing_search_rows(ids) do
547-
Enum.each(Enum.chunk_every(ids, @batch_size), fn batch ->
548-
placeholders = Enum.map_join(batch, ",", fn _ -> "?" end)
549-
550-
Repo.query!(
551-
"DELETE FROM scryfall_printing_search WHERE scryfall_id IN (#{placeholders})",
552-
batch
553-
)
554-
end)
555-
end
556-
557477
defp import_timestamp(false), do: utc_now()
558478

559479
defp import_timestamp(true) do

‎lib/manavault/catalog/scryfall/import_rows.ex‎

Lines changed: 4 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,17 @@ defmodule Manavault.Catalog.Scryfall.ImportRows do
55
alias Manavault.Catalog.Search.NameMatch
66

77
def rows(cards, now, oracle_tag_index) when is_list(cards) do
8-
{card_rows, printing_rows, search_rows} =
9-
Enum.reduce(cards, {[], [], []}, fn card, {card_rows, printing_rows, search_rows} ->
8+
{card_rows, printing_rows} =
9+
Enum.reduce(cards, {[], []}, fn card, {card_rows, printing_rows} ->
1010
{
1111
prepend_rows(card_row(card, now, oracle_tag_index), card_rows),
12-
prepend_rows(printing_row(card, now), printing_rows),
13-
prepend_rows(printing_search_row(card), search_rows)
12+
prepend_rows(printing_row(card, now), printing_rows)
1413
}
1514
end)
1615

1716
%{
1817
cards: :lists.reverse(card_rows),
19-
printings: :lists.reverse(printing_rows),
20-
search_rows: :lists.reverse(search_rows)
18+
printings: :lists.reverse(printing_rows)
2119
}
2220
end
2321

@@ -29,10 +27,6 @@ defmodule Manavault.Catalog.Scryfall.ImportRows do
2927
Enum.flat_map(cards, &printing_row(&1, now))
3028
end
3129

32-
def printing_search_rows(cards) when is_list(cards) do
33-
Enum.flat_map(cards, &printing_search_row/1)
34-
end
35-
3630
defp prepend_rows(rows, acc) do
3731
Enum.reduce(rows, acc, fn row, rows -> [row | rows] end)
3832
end
@@ -96,43 +90,6 @@ defmodule Manavault.Catalog.Scryfall.ImportRows do
9690

9791
defp printing_row(_card, _now), do: []
9892

99-
defp printing_search_row(%{"id" => scryfall_id, "name" => name} = card)
100-
when is_binary(scryfall_id) and is_binary(name) do
101-
oracle_text = oracle_text(card) || ""
102-
103-
[
104-
%{
105-
scryfall_id: scryfall_id,
106-
name: normalize_search_text(name),
107-
compact_name: compact_search_text(name),
108-
flavor_name: normalize_search_text(flavor_name(card) || ""),
109-
compact_flavor_name: compact_search_text(flavor_name(card) || ""),
110-
flavor_text: normalize_search_text(flavor_text(card) || ""),
111-
compact_flavor_text: compact_search_text(flavor_text(card) || ""),
112-
type_line: normalize_search_text(card["type_line"] || ""),
113-
oracle_text: normalize_search_text(oracle_text),
114-
compact_oracle_text: compact_search_text(oracle_text),
115-
set_code: normalize_search_text(card["set"] || ""),
116-
collector_number: normalize_search_text(card["collector_number"] || "")
117-
}
118-
]
119-
end
120-
121-
defp printing_search_row(_card), do: []
122-
123-
defp normalize_search_text(value) when is_binary(value) do
124-
value
125-
|> String.downcase()
126-
|> String.replace(~r/[^a-z0-9]+/u, " ")
127-
|> String.trim()
128-
end
129-
130-
defp compact_search_text(value) when is_binary(value) do
131-
value
132-
|> String.downcase()
133-
|> String.replace(~r/[^a-z0-9]+/u, "")
134-
end
135-
13693
defp colors(%{"colors" => colors}) when is_list(colors), do: colors
13794

13895
defp colors(%{"card_faces" => [%{"colors" => colors} | _faces]}) when is_list(colors),
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
defmodule Manavault.Repo.Migrations.DropScryfallPrintingSearch do
2+
use Ecto.Migration
3+
4+
# The FTS5 table was maintained on every Scryfall import (~100 MB for the
5+
# full catalog) but no query ever read it. Card and collection search run
6+
# against the covering indexes on scryfall_cards / scryfall_printings.
7+
8+
def up do
9+
execute("DROP TABLE IF EXISTS scryfall_printing_search")
10+
end
11+
12+
def down do
13+
execute("""
14+
CREATE VIRTUAL TABLE scryfall_printing_search USING fts5(
15+
scryfall_id UNINDEXED,
16+
name,
17+
compact_name,
18+
flavor_name,
19+
compact_flavor_name,
20+
flavor_text,
21+
compact_flavor_text,
22+
type_line,
23+
oracle_text,
24+
compact_oracle_text,
25+
set_code,
26+
collector_number
27+
)
28+
""")
29+
30+
execute("""
31+
INSERT INTO scryfall_printing_search (
32+
scryfall_id,
33+
name,
34+
compact_name,
35+
flavor_name,
36+
compact_flavor_name,
37+
flavor_text,
38+
compact_flavor_text,
39+
type_line,
40+
oracle_text,
41+
compact_oracle_text,
42+
set_code,
43+
collector_number
44+
)
45+
SELECT
46+
p.scryfall_id,
47+
lower(c.name),
48+
lower(replace(replace(replace(replace(replace(replace(c.name, ' ', ''), ',', ''), '''', ''), '’', ''), '-', ''), '/', '')),
49+
lower(coalesce(p.flavor_name, '')),
50+
lower(replace(replace(replace(replace(replace(replace(coalesce(p.flavor_name, ''), ' ', ''), ',', ''), '''', ''), '’', ''), '-', ''), '/', '')),
51+
lower(coalesce(p.flavor_text, '')),
52+
lower(replace(replace(replace(replace(replace(replace(coalesce(p.flavor_text, ''), ' ', ''), ',', ''), '''', ''), '’', ''), '-', ''), '/', '')),
53+
lower(coalesce(c.type_line, '')),
54+
lower(coalesce(c.oracle_text, '')),
55+
lower(replace(replace(replace(replace(replace(replace(coalesce(c.oracle_text, ''), ' ', ''), ',', ''), '''', ''), '’', ''), '-', ''), '/', '')),
56+
lower(p.set_code),
57+
lower(p.collector_number)
58+
FROM scryfall_printings p
59+
JOIN scryfall_cards c ON c.oracle_id = p.oracle_id
60+
""")
61+
end
62+
end

‎test/manavault/backup/create_test.exs‎

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ defmodule Manavault.Backup.CreateTest do
1717
alias Manavault.Backup.CreateTestRepo
1818

1919
@catalog_tables ~w[
20-
scryfall_printing_search
2120
scryfall_syncs
2221
scryfall_printings
2322
scryfall_cards
@@ -97,11 +96,6 @@ defmodule Manavault.Backup.CreateTest do
9796
collector_number TEXT NOT NULL
9897
);
9998
100-
CREATE VIRTUAL TABLE scryfall_printing_search USING fts5(
101-
scryfall_id UNINDEXED,
102-
name
103-
);
104-
10599
CREATE TABLE scryfall_syncs (
106100
id INTEGER PRIMARY KEY,
107101
status TEXT NOT NULL,
@@ -120,9 +114,6 @@ defmodule Manavault.Backup.CreateTest do
120114
INSERT INTO scryfall_printings (scryfall_id, oracle_id, set_code, collector_number)
121115
VALUES ('printing-1', 'oracle-1', 'lea', '232');
122116
123-
INSERT INTO scryfall_printing_search (scryfall_id, name)
124-
VALUES ('printing-1', 'black lotus');
125-
126117
INSERT INTO scryfall_syncs (status, bulk_type)
127118
VALUES ('completed', 'default_cards');
128119

‎test/manavault/catalog/import_test.exs‎

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,9 @@ defmodule Manavault.Catalog.ImportTest do
8282
refute Repo.get(Printing, memorabilia["id"])
8383
refute Repo.get(Printing, token["id"])
8484
refute Repo.get(Card, token["oracle_id"])
85-
86-
assert %{rows: []} =
87-
Repo.query!(
88-
"SELECT scryfall_id FROM scryfall_printing_search WHERE scryfall_id IN (?, ?)",
89-
[memorabilia["id"], token["id"]]
90-
)
9185
end
9286

93-
test "import_cards releases the write lock between batches without dropping search rows" do
87+
test "import_cards releases the write lock between batches" do
9488
test_pid = self()
9589
handler_id = {__MODULE__, make_ref()}
9690

‎test/manavault/catalog/sync_test.exs‎

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,6 @@ defmodule Manavault.Catalog.SyncTest do
250250
assert Repo.get!(Printing, @black_lotus["id"])
251251
refute Repo.get(Printing, memorabilia["id"])
252252
refute Repo.get(Printing, token["id"])
253-
254-
assert %{rows: []} =
255-
Repo.query!(
256-
"SELECT scryfall_id FROM scryfall_printing_search WHERE scryfall_id IN (?, ?)",
257-
[memorabilia["id"], token["id"]]
258-
)
259253
end
260254

261255
test "sync_scryfall only runs the paper printing reconciliation once" do
@@ -323,8 +317,7 @@ defmodule Manavault.Catalog.SyncTest do
323317
assert log =~ "Scryfall catalog sync downloaded default-cards bulk"
324318
assert log =~ "Scryfall catalog sync decoded default-cards bulk"
325319

326-
assert log =~
327-
"Scryfall catalog import progress source_cards=1/1 cards=1 printings=1 search_rows=1"
320+
assert log =~ "Scryfall catalog import progress source_cards=1/1 cards=1 printings=1"
328321

329322
assert log =~ "Scryfall catalog import completed source_cards=1 cards=1 printings=1"
330323
assert log =~ "Scryfall catalog sync succeeded"

0 commit comments

Comments
 (0)