1use super::*;
6use rbp_cards::*;
7use rbp_gameplay::*;
8
9impl Schema for Street {
10 fn name() -> &'static str {
11 STREET
12 }
13 fn creates() -> &'static str {
14 const_format::concatcp!(
15 "CREATE TABLE IF NOT EXISTS ",
16 STREET,
17 " (
18 street SMALLINT,
19 nobs INTEGER,
20 nabs INTEGER
21 );
22 TRUNCATE TABLE ",
23 STREET,
24 ";
25 CREATE OR REPLACE FUNCTION get_nabs(s SMALLINT) RETURNS INTEGER AS
26 $$ BEGIN RETURN (SELECT COUNT(*) FROM ",
27 ABSTRACTION,
28 " a WHERE a.street = s); END; $$
29 LANGUAGE plpgsql;"
30 )
31 }
32 fn indices() -> &'static str {
33 const_format::concatcp!(
34 "CREATE INDEX IF NOT EXISTS idx_",
35 STREET,
36 "_st ON ",
37 STREET,
38 " (street);"
39 )
40 }
41 fn copy() -> &'static str {
42 unimplemented!("Street is derived, not loaded from files")
43 }
44 fn truncates() -> &'static str {
45 const_format::concatcp!("TRUNCATE TABLE ", STREET, ";")
46 }
47 fn freeze() -> &'static str {
48 const_format::concatcp!(
49 "ALTER TABLE ",
50 STREET,
51 " SET (fillfactor = 100);
52 ALTER TABLE ",
53 STREET,
54 " SET (autovacuum_enabled = false);"
55 )
56 }
57 fn columns() -> &'static [tokio_postgres::types::Type] {
58 unimplemented!("Street is derived, not loaded from files")
59 }
60}
61
62impl Derive for Street {
63 fn exhaust() -> Vec<Self> {
64 Street::all().iter().rev().copied().collect()
65 }
66 fn inserts(&self) -> String {
67 let s = *self as i16;
68 let n = self.n_isomorphisms() as i32;
69 format!(
70 "INSERT INTO {} (street, nobs, nabs) VALUES ({}, {}, get_nabs({}::SMALLINT));",
71 STREET, s, n, s
72 )
73 }
74}
75
76impl Schema for Abstraction {
77 fn name() -> &'static str {
78 ABSTRACTION
79 }
80 fn creates() -> &'static str {
81 const_format::concatcp!(
82 "CREATE TABLE IF NOT EXISTS ",
83 ABSTRACTION,
84 " (
85 abs SMALLINT,
86 street SMALLINT,
87 population INTEGER,
88 equity REAL
89 );
90 TRUNCATE TABLE ",
91 ABSTRACTION,
92 ";
93 CREATE OR REPLACE FUNCTION get_population(xxx SMALLINT) RETURNS INTEGER AS
94 $$ BEGIN RETURN (SELECT COUNT(*) FROM ",
95 ISOMORPHISM,
96 " e WHERE e.abs = xxx); END; $$
97 LANGUAGE plpgsql;
98 CREATE OR REPLACE FUNCTION get_street_abs(abs SMALLINT) RETURNS SMALLINT AS
99 $$ BEGIN RETURN ((abs >> 8) & 255)::SMALLINT; END; $$
100 LANGUAGE plpgsql;
101 CREATE OR REPLACE FUNCTION get_equity(parent SMALLINT) RETURNS REAL AS
102 $$ BEGIN RETURN CASE WHEN get_street_abs(parent) = 3
103 THEN (parent & 255)::REAL / 100
104 ELSE (
105 SELECT COALESCE(SUM(t.dx * r.equity) / NULLIF(SUM(t.dx), 0), 0)
106 FROM ",
107 TRANSITIONS,
108 " t
109 JOIN ",
110 ABSTRACTION,
111 " r ON t.next = r.abs
112 WHERE t.prev = parent) END; END; $$
113 LANGUAGE plpgsql;"
114 )
115 }
116 fn indices() -> &'static str {
117 const_format::concatcp!(
118 "CREATE INDEX IF NOT EXISTS idx_",
119 ABSTRACTION,
120 "_abs ON ",
121 ABSTRACTION,
122 " (abs);
123 CREATE INDEX IF NOT EXISTS idx_",
124 ABSTRACTION,
125 "_st ON ",
126 ABSTRACTION,
127 " (street);
128 CREATE INDEX IF NOT EXISTS idx_",
129 ABSTRACTION,
130 "_eq ON ",
131 ABSTRACTION,
132 " (equity);
133 CREATE INDEX IF NOT EXISTS idx_",
134 ABSTRACTION,
135 "_pop ON ",
136 ABSTRACTION,
137 " (population);"
138 )
139 }
140 fn copy() -> &'static str {
141 unimplemented!("Abstraction is derived, not loaded from files")
142 }
143 fn truncates() -> &'static str {
144 const_format::concatcp!("TRUNCATE TABLE ", ABSTRACTION, ";")
145 }
146 fn freeze() -> &'static str {
147 const_format::concatcp!(
148 "ALTER TABLE ",
149 ABSTRACTION,
150 " SET (fillfactor = 100);
151 ALTER TABLE ",
152 ABSTRACTION,
153 " SET (autovacuum_enabled = false);"
154 )
155 }
156 fn columns() -> &'static [tokio_postgres::types::Type] {
157 unimplemented!("Abstraction is derived, not loaded from files")
158 }
159}
160
161impl Derive for Abstraction {
162 fn exhaust() -> Vec<Self> {
163 Street::all()
164 .iter()
165 .rev()
166 .copied()
167 .flat_map(Abstraction::all)
168 .collect()
169 }
170 fn inserts(&self) -> String {
171 let abs = i16::from(*self);
172 format!(
173 "INSERT INTO {} (abs, street, equity, population) VALUES ({}, get_street_abs({}::SMALLINT), get_equity({}::SMALLINT), get_population({}::SMALLINT));",
174 ABSTRACTION, abs, abs, abs, abs
175 )
176 }
177}