Skip to content

Commit b89969f

Browse files
authored
Merge pull request #207 from plural/position_in_set
Position in set
2 parents 55b7b67 + e6c0d86 commit b89969f

File tree

42 files changed

+341
-39
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+341
-39
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ module Public
44
class Api::V3::Public::CardCycleResource < JSONAPI::Resource
55
immutable
66

7-
attributes :name, :date_release, :legacy_code, :card_set_ids, :updated_at
7+
attributes :name, :date_release, :legacy_code, :card_set_ids, :first_printing_id, :updated_at
88
key_type :string
99

1010
has_many :card_sets
1111
has_many :cards, relation_name: :unified_cards
1212
has_many :printings, relation_name: :unified_printings
1313

1414
paginator :none
15+
16+
def first_printing_id
17+
UnifiedPrinting.where(card_cycle_id: @model.id).minimum(:id)
18+
end
1519
end
1620
end
1721
end

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module Public
44
class Api::V3::Public::CardSetResource < JSONAPI::Resource
55
immutable
66

7-
attributes :name, :date_release, :size, :card_cycle_id, :card_set_type_id, :legacy_code, :updated_at
7+
attributes :name, :date_release, :size, :card_cycle_id, :card_set_type_id, :legacy_code, :first_printing_id, :updated_at
88
key_type :string
99

1010
paginator :none
@@ -15,6 +15,12 @@ class Api::V3::Public::CardSetResource < JSONAPI::Resource
1515
has_many :cards, relation_name: :unified_cards
1616

1717
filters :card_cycle_id, :card_set_type_id
18+
19+
def first_printing_id
20+
first_printing = @model.printings.find_by(position_in_set: 1)
21+
return if first_printing.nil?
22+
first_printing.id
23+
end
1824
end
1925
end
2026
end

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Api::V3::Public::PrintingResource < JSONAPI::Resource
1010

1111
# Direct printing attributes
1212
attributes :card_id, :card_cycle_id, :card_cycle_name, :card_set_id, :card_set_name
13-
attributes :flavor, :display_illustrators, :illustrator_ids, :illustrator_names, :position
13+
attributes :flavor, :display_illustrators, :illustrator_ids, :illustrator_names, :position, :position_in_set
1414
attributes :quantity, :date_release, :updated_at
1515

1616
# Parent Card attributes, included inline to make printings a bit more useful.
@@ -57,7 +57,7 @@ def restrictions
5757
end
5858

5959
# Printing direct attribute filters
60-
filters :card_id, :card_set_id, :display_illustrators, :position
60+
filters :card_id, :card_set_id, :display_illustrators, :position, :position_in_set
6161
filters :quantity, :date_release
6262

6363
# Card attribute filters
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddPositionInSet < ActiveRecord::Migration[7.0]
2+
def change
3+
add_column :printings, :position_in_set, :int
4+
end
5+
end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class UpdateUnifiedPrintingsToVersion4 < ActiveRecord::Migration[7.0]
2+
def change
3+
4+
update_view :unified_printings, version: 4, revert_to_version: 3, materialized: true
5+
end
6+
end

db/schema.rb

Lines changed: 3 additions & 1 deletion
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: 2023_08_21_014459) do
13+
ActiveRecord::Schema[7.0].define(version: 2023_09_23_064748) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "pgcrypto"
1616
enable_extension "plpgsql"
@@ -191,6 +191,7 @@
191191
t.date "date_release"
192192
t.datetime "created_at", null: false
193193
t.datetime "updated_at", null: false
194+
t.integer "position_in_set"
194195
end
195196

196197
create_table "restrictions", id: :string, force: :cascade do |t|
@@ -631,6 +632,7 @@
631632
p.flavor,
632633
p.display_illustrators,
633634
p."position",
635+
p.position_in_set,
634636
p.quantity,
635637
p.date_release,
636638
p.created_at,

db/views/unified_printings_v04.sql

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

doc/api/card_cycles/all_card_cycles.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"request_content_type": "application/json",
2626
"response_status": 200,
2727
"response_status_text": "OK",
28-
"response_body": "{\n \"data\": [\n {\n \"id\": \"borealis\",\n \"type\": \"card_cycles\",\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis\"\n },\n \"attributes\": {\n \"name\": \"Borealis\",\n \"date_release\": \"2022-07-22\",\n \"legacy_code\": \"borealis\",\n \"card_set_ids\": [\n \"midnight_sun\",\n \"parhelion\"\n ],\n \"updated_at\": \"2022-12-08T12:00:00.000Z\"\n },\n \"relationships\": {\n \"card_sets\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/relationships/card_sets\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/card_sets\"\n }\n },\n \"cards\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/relationships/cards\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/cards\"\n }\n },\n \"printings\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/relationships/printings\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/printings\"\n }\n }\n }\n },\n {\n \"id\": \"core\",\n \"type\": \"card_cycles\",\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core\"\n },\n \"attributes\": {\n \"name\": \"Core Set\",\n \"date_release\": \"2012-09-06\",\n \"legacy_code\": \"core\",\n \"card_set_ids\": [\n \"core\"\n ],\n \"updated_at\": \"2022-12-08T12:00:00.000Z\"\n },\n \"relationships\": {\n \"card_sets\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/relationships/card_sets\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/card_sets\"\n }\n },\n \"cards\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/relationships/cards\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/cards\"\n }\n },\n \"printings\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/relationships/printings\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/printings\"\n }\n }\n }\n }\n ]\n}",
28+
"response_body": "{\n \"data\": [\n {\n \"id\": \"borealis\",\n \"type\": \"card_cycles\",\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis\"\n },\n \"attributes\": {\n \"name\": \"Borealis\",\n \"date_release\": \"2022-07-22\",\n \"legacy_code\": \"borealis\",\n \"card_set_ids\": [\n \"midnight_sun\",\n \"parhelion\"\n ],\n \"first_printing_id\": null,\n \"updated_at\": \"2022-12-08T12:00:00.000Z\"\n },\n \"relationships\": {\n \"card_sets\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/relationships/card_sets\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/card_sets\"\n }\n },\n \"cards\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/relationships/cards\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/cards\"\n }\n },\n \"printings\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/relationships/printings\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/borealis/printings\"\n }\n }\n }\n },\n {\n \"id\": \"core\",\n \"type\": \"card_cycles\",\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core\"\n },\n \"attributes\": {\n \"name\": \"Core Set\",\n \"date_release\": \"2012-09-06\",\n \"legacy_code\": \"core\",\n \"card_set_ids\": [\n \"core\"\n ],\n \"first_printing_id\": \"01050\",\n \"updated_at\": \"2022-12-08T12:00:00.000Z\"\n },\n \"relationships\": {\n \"card_sets\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/relationships/card_sets\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/card_sets\"\n }\n },\n \"cards\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/relationships/cards\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/cards\"\n }\n },\n \"printings\": {\n \"links\": {\n \"self\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/relationships/printings\",\n \"related\": \"http://api-preview.netrunnerdb.com/api/v3/public/card_cycles/core/printings\"\n }\n }\n }\n }\n ]\n}",
2929
"response_headers": {
3030
"Content-Type": "application/vnd.api+json"
3131
},

0 commit comments

Comments
 (0)