Skip to content

Commit fa52335

Browse files
authored
Merge pull request #114 from distributive/main
Added the attribution field to cards
2 parents fa4f774 + f77e191 commit fa52335

File tree

7 files changed

+330
-6
lines changed

7 files changed

+330
-6
lines changed

app/resources/api/v3/public/card_resource.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Api::V3::Public::CardResource < JSONAPI::Resource
1010
attributes :advancement_requirement, :agenda_points, :base_link, :cost
1111
attributes :deck_limit, :in_restriction, :influence_cost, :influence_limit, :memory_cost
1212
attributes :minimum_deck_size, :latest_printing_id, :num_printings, :printing_ids, :restriction_ids, :restrictions, :strength, :stripped_text, :text, :trash_cost
13-
attributes :is_unique, :card_subtype_ids, :display_subtypes, :updated_at
13+
attributes :is_unique, :card_subtype_ids, :display_subtypes, :attribution, :updated_at
1414
attributes :card_abilities, :format_ids, :card_pool_ids, :snapshot_ids
1515

1616
key_type :string
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class AddAttributionToCard < ActiveRecord::Migration[7.0]
2+
def change
3+
add_column :cards, :attribution, :string
4+
update_view :unified_cards, materialized: true, version: 2, revert_to_version: 1
5+
end
6+
end

db/schema.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.0].define(version: 2022_09_26_010740) do
13+
ActiveRecord::Schema[7.0].define(version: 2022_10_24_132405) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "plpgsql"
1616

@@ -115,6 +115,7 @@
115115
t.integer "recurring_credits_provided"
116116
t.boolean "rez_effect", default: false
117117
t.boolean "trash_ability", default: false
118+
t.string "attribution"
118119
t.index ["card_type_id"], name: "index_cards_on_card_type_id"
119120
t.index ["faction_id"], name: "index_cards_on_faction_id"
120121
t.index ["side_id"], name: "index_cards_on_side_id"
@@ -426,6 +427,7 @@
426427
c.trash_cost,
427428
c.is_unique,
428429
c.display_subtypes,
430+
c.attribution,
429431
c.created_at,
430432
c.updated_at,
431433
c.additional_cost,
@@ -474,6 +476,6 @@
474476
LEFT JOIN format_ids f ON (((c.id)::text = f.card_id)))
475477
LEFT JOIN card_pool_ids cpc ON (((c.id)::text = cpc.card_id)))
476478
LEFT JOIN snapshot_ids s ON (((c.id)::text = s.card_id)))
477-
GROUP BY c.id, c.title, c.stripped_title, c.card_type_id, c.side_id, c.faction_id, c.advancement_requirement, c.agenda_points, c.base_link, c.cost, c.deck_limit, c.influence_cost, c.influence_limit, c.memory_cost, c.minimum_deck_size, c.strength, c.stripped_text, c.text, c.trash_cost, c.is_unique, c.display_subtypes, c.created_at, c.updated_at, c.additional_cost, c.advanceable, c.gains_subroutines, c.interrupt, c.link_provided, c.mu_provided, c.num_printed_subroutines, c.on_encounter_effect, c.performs_trace, c.recurring_credits_provided, c.rez_effect, c.trash_ability, csi.card_subtype_ids, csn.lower_card_subtype_names, csn.card_subtype_names, p.printing_ids, ccs.card_cycle_ids, ccs.card_cycle_names, css.card_set_ids, css.card_set_names, r.restriction_ids, r_b.restrictions_banned, r_g_p.restrictions_global_penalty, r_p.restrictions_points, r_r.restrictions_restricted, r_u_f_c.restrictions_universal_faction_cost, f.format_ids, cpc.card_pool_ids, s.snapshot_ids;
479+
GROUP BY c.id, c.title, c.stripped_title, c.card_type_id, c.side_id, c.faction_id, c.advancement_requirement, c.agenda_points, c.base_link, c.cost, c.deck_limit, c.influence_cost, c.influence_limit, c.memory_cost, c.minimum_deck_size, c.strength, c.stripped_text, c.text, c.trash_cost, c.is_unique, c.display_subtypes, c.attribution, c.created_at, c.updated_at, c.additional_cost, c.advanceable, c.gains_subroutines, c.interrupt, c.link_provided, c.mu_provided, c.num_printed_subroutines, c.on_encounter_effect, c.performs_trace, c.recurring_credits_provided, c.rez_effect, c.trash_ability, csi.card_subtype_ids, csn.lower_card_subtype_names, csn.card_subtype_names, p.printing_ids, ccs.card_cycle_ids, ccs.card_cycle_names, css.card_set_ids, css.card_set_names, r.restriction_ids, r_b.restrictions_banned, r_g_p.restrictions_global_penalty, r_p.restrictions_points, r_r.restrictions_restricted, r_u_f_c.restrictions_universal_faction_cost, f.format_ids, cpc.card_pool_ids, s.snapshot_ids;
478480
SQL
479481
end

db/views/unified_cards_v02.sql

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
WITH card_cycles_summary AS (
2+
SELECT
3+
c.id,
4+
ARRAY_AGG(
5+
cc.id ORDER BY cc.id
6+
) as card_cycle_ids,
7+
ARRAY_AGG(
8+
LOWER(cc.name) ORDER BY LOWER(cc.name)
9+
) as card_cycle_names
10+
FROM
11+
cards c
12+
JOIN printings p ON c.id = p.card_id
13+
JOIN card_sets cs ON p.card_set_id = cs.id
14+
JOIN card_cycles cc ON cc.id = cs.card_cycle_id
15+
GROUP BY
16+
c.id
17+
),
18+
card_sets_summary AS (
19+
SELECT
20+
c.id,
21+
ARRAY_AGG(
22+
cs.id ORDER BY cs.id
23+
) as card_set_ids,
24+
ARRAY_AGG(
25+
LOWER(cs.name) ORDER BY LOWER(cs.name)
26+
) as card_set_names
27+
FROM
28+
cards c
29+
JOIN printings p ON c.id = p.card_id
30+
JOIN card_sets cs ON p.card_set_id = cs.id
31+
GROUP BY
32+
c.id
33+
),
34+
card_subtype_ids AS (
35+
SELECT
36+
card_id,
37+
ARRAY_AGG(
38+
card_subtype_id
39+
ORDER BY
40+
1
41+
) as card_subtype_ids
42+
FROM
43+
cards_card_subtypes
44+
GROUP BY
45+
card_id
46+
),
47+
card_subtype_names AS (
48+
SELECT
49+
ccs.card_id,
50+
-- lower used for filtering
51+
ARRAY_AGG(
52+
LOWER(cs.name) ORDER BY LOWER(cs.name)
53+
) as lower_card_subtype_names,
54+
-- proper case used for display
55+
ARRAY_AGG(
56+
cs.name ORDER BY cs.name
57+
) as card_subtype_names
58+
FROM
59+
cards_card_subtypes ccs
60+
JOIN card_subtypes cs ON ccs.card_subtype_id = cs.id
61+
GROUP BY
62+
ccs.card_id
63+
),
64+
card_printing_ids AS (
65+
SELECT
66+
card_id,
67+
ARRAY_AGG(
68+
id ORDER BY date_release DESC
69+
) as printing_ids
70+
FROM
71+
printings
72+
GROUP BY
73+
card_id
74+
),
75+
card_restriction_ids AS (
76+
SELECT
77+
card_id,
78+
ARRAY_AGG(
79+
restriction_id ORDER BY restriction_id
80+
) as restriction_ids
81+
FROM
82+
unified_restrictions
83+
WHERE
84+
in_restriction
85+
GROUP BY
86+
1
87+
),
88+
restrictions_banned_summary AS (
89+
SELECT
90+
card_id,
91+
ARRAY_AGG(
92+
restriction_id ORDER BY restriction_id
93+
) as restrictions_banned
94+
FROM
95+
restrictions_cards_banned
96+
GROUP BY
97+
card_id
98+
),
99+
restrictions_global_penalty_summary AS (
100+
SELECT
101+
card_id,
102+
ARRAY_AGG(
103+
restriction_id ORDER BY restriction_id
104+
) as restrictions_global_penalty
105+
FROM
106+
restrictions_cards_global_penalty
107+
GROUP BY
108+
card_id
109+
),
110+
restrictions_points_summary AS (
111+
SELECT
112+
card_id,
113+
ARRAY_AGG(
114+
CONCAT(restriction_id, '=', CAST (value AS text))
115+
ORDER BY CONCAT(restriction_id, '=', CAST (value AS text))
116+
) as restrictions_points
117+
FROM
118+
restrictions_cards_points
119+
GROUP BY
120+
card_id
121+
),
122+
restrictions_restricted_summary AS (
123+
SELECT
124+
card_id,
125+
ARRAY_AGG(
126+
restriction_id ORDER BY restriction_id
127+
) as restrictions_restricted
128+
FROM
129+
restrictions_cards_restricted
130+
GROUP BY
131+
card_id
132+
),
133+
restrictions_universal_faction_cost_summary AS (
134+
SELECT
135+
card_id,
136+
ARRAY_AGG(
137+
CONCAT(restriction_id, '=', CAST (value AS text))
138+
ORDER BY CONCAT(restriction_id, '=', CAST (value AS text))
139+
) as restrictions_universal_faction_cost
140+
FROM
141+
restrictions_cards_universal_faction_cost
142+
GROUP BY
143+
card_id
144+
),
145+
format_ids AS (
146+
SELECT
147+
cpc.card_id,
148+
ARRAY_AGG(
149+
DISTINCT s.format_id ORDER BY s.format_id
150+
) as format_ids
151+
FROM
152+
card_pools_cards cpc
153+
JOIN snapshots s ON cpc.card_pool_id = s.card_pool_id
154+
GROUP BY
155+
cpc.card_id
156+
),
157+
card_pool_ids AS (
158+
SELECT
159+
cpc.card_id,
160+
ARRAY_AGG(
161+
DISTINCT s.card_pool_id ORDER BY s.card_pool_id
162+
) as card_pool_ids
163+
FROM
164+
card_pools_cards cpc
165+
JOIN snapshots s ON cpc.card_pool_id = s.card_pool_id
166+
GROUP BY
167+
cpc.card_id
168+
),
169+
snapshot_ids AS (
170+
SELECT
171+
cpc.card_id,
172+
ARRAY_AGG(
173+
DISTINCT s.id ORDER BY s.id
174+
) as snapshot_ids
175+
FROM
176+
card_pools_cards cpc
177+
JOIN snapshots s ON cpc.card_pool_id = s.card_pool_id
178+
GROUP BY
179+
cpc.card_id
180+
)
181+
SELECT
182+
c.id as id,
183+
c.title,
184+
c.stripped_title,
185+
c.card_type_id,
186+
c.side_id,
187+
c.faction_id,
188+
c.advancement_requirement,
189+
c.agenda_points,
190+
c.base_link,
191+
c.cost,
192+
c.deck_limit,
193+
c.influence_cost,
194+
c.influence_limit,
195+
c.memory_cost,
196+
c.minimum_deck_size,
197+
c.strength,
198+
c.stripped_text,
199+
c.text,
200+
c.trash_cost,
201+
c.is_unique,
202+
c.display_subtypes,
203+
c.attribution,
204+
c.created_at,
205+
c.updated_at,
206+
c.additional_cost,
207+
c.advanceable,
208+
c.gains_subroutines,
209+
c.interrupt,
210+
c.link_provided,
211+
c.mu_provided,
212+
c.num_printed_subroutines,
213+
c.on_encounter_effect,
214+
c.performs_trace,
215+
c.recurring_credits_provided,
216+
c.rez_effect,
217+
c.trash_ability,
218+
COALESCE(csi.card_subtype_ids, ARRAY [] :: text []) as card_subtype_ids,
219+
COALESCE(csn.lower_card_subtype_names, ARRAY [] :: text []) as lower_card_subtype_names,
220+
COALESCE(csn.card_subtype_names, ARRAY [] :: text []) as card_subtype_names,
221+
p.printing_ids,
222+
ARRAY_LENGTH(p.printing_ids, 1) AS num_printings,
223+
ccs.card_cycle_ids,
224+
ccs.card_cycle_names,
225+
css.card_set_ids,
226+
css.card_set_names,
227+
COALESCE(r.restriction_ids, ARRAY [] :: text []) as restriction_ids,
228+
r.restriction_ids IS NOT NULL as in_restriction,
229+
COALESCE(r_b.restrictions_banned, ARRAY [] :: text []) as restrictions_banned,
230+
COALESCE(
231+
r_g_p.restrictions_global_penalty,
232+
ARRAY [] :: text []
233+
) as restrictions_global_penalty,
234+
COALESCE(r_p.restrictions_points, ARRAY [] :: text []) as restrictions_points,
235+
COALESCE(r_r.restrictions_restricted, ARRAY [] :: text []) as restrictions_restricted,
236+
COALESCE(
237+
r_u_f_c.restrictions_universal_faction_cost,
238+
ARRAY [] :: text []
239+
) as restrictions_universal_faction_cost,
240+
COALESCE(f.format_ids, ARRAY [] :: text []) as format_ids,
241+
COALESCE(cpc.card_pool_ids, ARRAY [] :: text []) as card_pool_ids,
242+
COALESCE(s.snapshot_ids, ARRAY [] :: text []) as snapshot_ids
243+
FROM
244+
cards c
245+
JOIN card_printing_ids p ON c.id = p.card_id
246+
JOIN card_cycles_summary ccs ON c.id = ccs.id
247+
JOIN card_sets_summary css ON c.id = css.id
248+
LEFT JOIN card_subtype_ids csi ON c.id = csi.card_id
249+
LEFT JOIN card_subtype_names csn ON c.id = csn.card_id
250+
LEFT JOIN card_restriction_ids r ON c.id = r.card_id
251+
LEFT JOIN restrictions_banned_summary r_b ON c.id = r_b.card_id
252+
LEFT JOIN restrictions_global_penalty_summary r_g_p ON c.id = r_g_p.card_id
253+
LEFT JOIN restrictions_points_summary r_p ON c.id = r_p.card_id
254+
LEFT JOIN restrictions_restricted_summary r_r ON c.id = r_r.card_id
255+
LEFT JOIN restrictions_universal_faction_cost_summary r_u_f_c ON c.id = r_u_f_c.card_id
256+
LEFT JOIN format_ids f ON c.id = f.card_id
257+
LEFT JOIN card_pool_ids cpc ON c.id = cpc.card_id
258+
LEFT JOIN snapshot_ids s ON c.id = s.card_id
259+
GROUP BY
260+
c.id,
261+
c.title,
262+
c.stripped_title,
263+
c.card_type_id,
264+
c.side_id,
265+
c.faction_id,
266+
c.advancement_requirement,
267+
c.agenda_points,
268+
c.base_link,
269+
c.cost,
270+
c.deck_limit,
271+
c.influence_cost,
272+
c.influence_limit,
273+
c.memory_cost,
274+
c.minimum_deck_size,
275+
c.strength,
276+
c.stripped_text,
277+
c.text,
278+
c.trash_cost,
279+
c.is_unique,
280+
c.display_subtypes,
281+
c.attribution,
282+
c.created_at,
283+
c.updated_at,
284+
c.additional_cost,
285+
c.advanceable,
286+
c.gains_subroutines,
287+
c.interrupt,
288+
c.link_provided,
289+
c.mu_provided,
290+
c.num_printed_subroutines,
291+
c.on_encounter_effect,
292+
c.performs_trace,
293+
c.recurring_credits_provided,
294+
c.rez_effect,
295+
c.trash_ability,
296+
csi.card_subtype_ids,
297+
csn.lower_card_subtype_names,
298+
csn.card_subtype_names,
299+
p.printing_ids,
300+
ccs.card_cycle_ids,
301+
ccs.card_cycle_names,
302+
css.card_set_ids,
303+
css.card_set_names,
304+
r.restriction_ids,
305+
r_b.restrictions_banned,
306+
r_g_p.restrictions_global_penalty,
307+
r_p.restrictions_points,
308+
r_r.restrictions_restricted,
309+
r_u_f_c.restrictions_universal_faction_cost,
310+
f.format_ids,
311+
cpc.card_pool_ids,
312+
s.snapshot_ids;

lib/card_search_parser.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class CardSearchParser < Parslet::Parser
2222
str('advanceable') |
2323
str('advancement_cost') |
2424
str('agenda_points') |
25+
str('attribution') |
2526
str('base_link') |
2627
str('card_cycle') |
2728
str('card_pool') |

lib/card_search_query_builder.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class CardSearchQueryBuilder
5656
]
5757
@@string_keywords = [
5858
'_',
59+
'attribution',
5960
'card_type',
6061
'd',
6162
'f',
@@ -94,6 +95,7 @@ class CardSearchQueryBuilder
9495
'advanceable' => 'unified_cards.advanceable',
9596
'advancement_cost' => 'unified_cards.advancement_requirement',
9697
'agenda_points' => 'unified_cards.agenda_points',
98+
'attribution' => 'unified_cards.attribution',
9799
'base_link' => 'unified_cards.base_link',
98100
'card_cycle' => 'unified_cards.card_cycle_ids',
99101
'card_pool' => 'unified_cards.card_pool_ids',
@@ -214,7 +216,7 @@ def initialize(query)
214216
return
215217
end
216218
constraints << '%s %s ?' % [@@term_to_field_map[keyword], operator]
217-
where << (value.downcase == 'x' ? -1 : value)
219+
where << (value.downcase == 'x' ? -1 : value)
218220
else
219221
# String fields only support : and !, resolving to to {,NOT} LIKE %value%.
220222
# TODO(plural): consider ~ for regex matches.

0 commit comments

Comments
 (0)