This repository has been archived by the owner on Jul 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
database_persistence.rb
232 lines (189 loc) · 4.59 KB
/
database_persistence.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
require "json"
require "pg"
require_relative "retrieve_trends"
class DBPersistence
attr_reader :locations
def initialize
@db = if Sinatra::Base.production?
PG.connect(ENV['DATABASE_URL'])
else
PG.connect(dbname: "trends")
end
@locations = get_locations
end
def delete_all
sql_1 = <<~SQL
DELETE FROM trends
SQL
sql_2 = <<~SQL
ALTER SEQUENCE trends_id_seq RESTART WITH 1
SQL
query(sql_1)
query(sql_2)
end
def reload_all
@locations.each { |loc| load_trends(loc) }
end
def disconnect
@db.close
end
def list_trends(location, sort_by, reversed)
sql = <<~SQL
SELECT t.id, t.name, t.volume
FROM trends AS t
INNER JOIN locations AS l
ON (t.location_id = l.id)
WHERE (l.name = $1)
ORDER BY #{sort_by}
SQL
sql = add_reverse(sql, reversed)
result = query(sql, location)
newRes = result.map do |tuple|
tuple_to_list_hash_trend(tuple)
end
alter_ids(newRes)
end
def town_volumes()
sql_volume = <<~SQL
SELECT l.name,
SUM(t.volume) AS total_volume
FROM trends AS t
INNER JOIN locations AS l
ON (t.location_id = l.id)
WHERE (l.id != 27)
GROUP BY l.id
ORDER BY l.id ASC;
SQL
town_volumes = query(sql_volume)
tuple_to_list_hash_volumes(town_volumes)
end
def town_top_trends()
sql_top_trends = <<~SQL
SELECT l.name AS town,
y.name AS trend,
y.volume
FROM (SELECT t.name,
t.location_id,
t.volume
FROM (SELECT location_id,
MAX(volume) as max_volume
FROM trends
GROUP BY location_id ) AS m
INNER JOIN trends AS t
ON (t.location_id = m.location_id)
AND (t.volume = m.max_volume)
WHERE (t.location_id != 27) ) AS y
INNER JOIN locations as l
ON (y.location_id = l.id);
SQL
trend_result = query(sql_top_trends)
tuple_to_list_hash_top_trends(trend_result)
end
private
def get_locations
sql = <<~SQL
SELECT name FROM locations
ORDER BY id;
SQL
result = query(sql)
result.values.map { |arr| arr[0] }
end
def query(sql, *params)
# puts "\n"
# puts sql
# puts "\n"
# puts params
# puts "\n" + "----------------------" + "\n"
@db.exec_params(sql, params)
end
def clear_trends(id)
sql = <<~SQL
DELETE FROM trends
WHERE (location_id = $1);
SQL
query(sql, id)
end
def load_trends(location)
loc_info = retrieve_loc_info(location)
loc_woeid = loc_info["woeid"].to_i
loc_id = loc_info["id"].to_i
trends = retrieve_loc_trends(loc_woeid)
return nil if trends == nil
clear_trends(loc_id)
sql = <<~SQL
INSERT INTO trends (name, volume, location_id)
VALUES ($1, $2, $3);
SQL
trends.each do |trend|
values = [ trend[0], trend[1], loc_id ]
query(sql, *values)
end
end
def retrieve_loc_trends(woeid)
api_location = RetrieveTrends.new(woeid)
api_location.trends
end
def retrieve_loc_info(location)
sql = <<~SQL
SELECT id,woeid FROM locations
WHERE name = ($1);
SQL
result = query(sql, location)
result.first
end
def load_locations
sql = <<~SQL
INSERT INTO locations (name, type, woeid )
VALUES ($1, $2, $3)
SQL
loc_json = File.read('data/gb_woeid.json')
loc_array = JSON.parse(loc_json)
loc_array.each do |loc|
values = [ loc["name"], loc["placeType"]["name"], loc["woeid"] ]
query(sql, *values)
end
end
def tuple_to_list_hash_volumes(result)
result.map do |tuple|
{
name: tuple["name"],
total_volume: tuple["total_volume"].to_i
}
end
end
def tuple_to_list_hash_top_trends(result)
result.map do |tuple|
{
name: tuple["town"],
trend: tuple["trend"],
trend_volume: tuple["volume"].to_i
}
end
end
def tuple_to_list_hash_trend(tuple)
{
id: tuple["id"].to_i,
name: tuple["name"],
volume: tuple["volume"].to_i
}
end
def add_reverse(sql, reversed = false)
asc = <<~SQL
ASC;
SQL
desc = <<~SQL
DESC;
SQL
sql += reversed ? desc : asc
end
def alter_ids(collection)
min_id = collection.map { |trend| trend[:id].to_i }.min
collection.map do |trend|
{
id: (trend[:id] - min_id),
name: trend[:name],
volume: trend[:volume],
}
end
end
end