1
|
package eu.dnetlib.goldoa.service.stats;
|
2
|
|
3
|
import eu.dnetlib.goldoa.domain.Request;
|
4
|
import eu.dnetlib.goldoa.domain.stats.Browse;
|
5
|
import eu.dnetlib.goldoa.domain.stats.DateSeries;
|
6
|
import eu.dnetlib.goldoa.domain.stats.MapData;
|
7
|
import eu.dnetlib.goldoa.domain.stats.Numbers;
|
8
|
import eu.dnetlib.goldoa.domain.stats.Quadruple;
|
9
|
import eu.dnetlib.goldoa.domain.stats.Series;
|
10
|
import eu.dnetlib.goldoa.domain.stats.Triple;
|
11
|
import org.springframework.beans.factory.annotation.Autowired;
|
12
|
import org.springframework.jdbc.core.JdbcTemplate;
|
13
|
import org.springframework.jdbc.core.RowMapper;
|
14
|
import org.springframework.transaction.annotation.Transactional;
|
15
|
|
16
|
import javax.sql.DataSource;
|
17
|
import java.sql.ResultSet;
|
18
|
import java.sql.SQLException;
|
19
|
import java.text.SimpleDateFormat;
|
20
|
import java.util.ArrayList;
|
21
|
import java.util.Date;
|
22
|
import java.util.HashMap;
|
23
|
import java.util.List;
|
24
|
import java.util.Map;
|
25
|
|
26
|
/**
|
27
|
* Created by antleb on 11/19/15.
|
28
|
*/
|
29
|
@Transactional(readOnly = true)
|
30
|
public class StatsManagerImpl implements StatsManager {
|
31
|
|
32
|
public static final String NUMBERS_REQUESTS = "select count(*) from request r where r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ")" ;
|
33
|
public static final String NUMBERS_PAID_REQUESTS = "select count(*) from request r where r.status in (" + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ")" ;
|
34
|
public static final String NUMBERS_PROJECTS = "select count(distinct project) from request r where r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ")";
|
35
|
public static final String NUMBERS_TOTAL_AMOUNT = "select sum(apc_paid) from request r";
|
36
|
public static final String NUMBERS_AVERAGE_AMOUNT = "select avg(apc_paid)::INTEGER from request r";
|
37
|
public static final String NUMBERS_AVERAGE_PER_ARTICLE = "select avg(apc_paid)::INTEGER from request r join publication p on r.publication=p.id where p.type='ARTICLE'";
|
38
|
public static final String NUMBERS_AVERAGE_PER_MONOGRAPH = "select avg(apc_paid)::INTEGER from request r join publication p on r.publication=p.id where p.type='MONOGRAPH'";
|
39
|
public static final String NUMBERS_AVERAGE_PER_BOOK_CHAPTER = "select avg(apc_paid)::INTEGER from request r join publication p on r.publication=p.id where p.type='BOOK_CHAPTER'";
|
40
|
public static final String NUMBERS_PAID_REQUESTS_WITH_DOI = "select count(*) from request r join publication p on r.publication=p.id where p.doi is not null and r.status=" + Request.RequestStatus.ACCOUNTING_PAID;
|
41
|
public static final String NUMBERS_APPROVED_REQUESTS_WITH_DOI = "select count(*) from request r join publication p on r.publication=p.id where p.doi is not null and r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ")";
|
42
|
|
43
|
public static final String SERIES_COUNTRY = "select c.name as category, count(r.id) as count, sum(apc_paid) as apc, avg(apc_paid) as avgapc from request r join organisation o on r.organization=o.id join country c on c.id=o.country %WHERE% group by c.name";
|
44
|
public static final String SERIES_STATUS = "select r.status as category, count(r.id) as count, sum(apc_paid) as apc, avg(apc_paid) as avgapc from request r %WHERE% group by r.status";
|
45
|
public static final String SERIES_TYPE = "select p.type as category, count(r.id) as count, sum(apc_paid) as apc, avg(apc_paid) as avgapc from request r join publication p on p.id=r.publication %WHERE% group by p.type";
|
46
|
public static final String SERIES_ORGANIZATION = "select o.name as category, count(r.id) as count, sum(apc_paid) as apc, avg(apc_paid) as avgapc from request r join organisation o on r.organization=o.id %WHERE% group by o.shortname, o.name";
|
47
|
public static final String SERIES_PUBLISHER = "select p.name as category, count(r.id) as count, sum(apc_paid) as apc, avg(apc_paid) as avgapc from (select r.id, r.status, r.apc_paid, j.publisher, 'j' from request r join journal j on r.journal=j.id where j.publisher is not null union select r.id, r.status, r.apc_paid, p.id, 'p' from request r join publisher p on r.publisher=p.id) as r join publisher p on r.publisher=p.id %WHERE% group by p.name";
|
48
|
|
49
|
public static final String BROWSE_SCIENTIFIC_AREA = "select distinct p.scientificarea as id, p.scientificarea as category, count(r.id) as count from request r join project p on r.project=p.id group by p.scientificarea order by category";
|
50
|
public static final String BROWSE_COUNTRY = "select c.id as id, c.name as category, count(r.id) as count from request r join organisation o on r.organization=o.id join country c on c.id=o.country group by c.name, c.id order by category";
|
51
|
public static final String BROWSE_ORGANIZATION = "select o.id as id, case when o.shortname is not null then o.shortname else o.name end as category, count(r.id) as count from request r join organisation o on o.id=r.organization group by o.shortname, o.name, o.id order by category";
|
52
|
public static final String BROWSE_PUBLISHER = "select p.id as id, p.name as category, count(r.id) as count from (select r.id, r.status, j.publisher, 'j' from request r join journal j on r.journal=j.id where j.publisher is not null union select r.id, r.status, p.id, 'p' from request r join publisher p on r.publisher=p.id) as r join publisher p on r.publisher=p.id group by p.name, p.id order by category";
|
53
|
public static final String BROWSE_STATUS = "select r.status as id, r.status as category, count(r.id) as count from request r group by status";
|
54
|
|
55
|
@Autowired
|
56
|
private DataSource dataSource;
|
57
|
|
58
|
@Override
|
59
|
public Numbers getNumbers(Numbers.Category[] categories) {
|
60
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
61
|
Map<Numbers.Category, Integer> map = new HashMap<Numbers.Category, Integer>();
|
62
|
|
63
|
for (Numbers.Category category:categories) {
|
64
|
switch (category) {
|
65
|
case REQUESTS:
|
66
|
map.put(Numbers.Category.REQUESTS, jdbcTemplate.queryForObject(NUMBERS_REQUESTS, Integer.class));
|
67
|
break;
|
68
|
case PAID_REQUESTS:
|
69
|
map.put(Numbers.Category.PAID_REQUESTS, jdbcTemplate.queryForObject(NUMBERS_PAID_REQUESTS, Integer.class));
|
70
|
break;
|
71
|
case PROJECTS:
|
72
|
map.put(Numbers.Category.PROJECTS, jdbcTemplate.queryForObject(NUMBERS_PROJECTS, Integer.class));
|
73
|
break;
|
74
|
case TOTAL_AMOUNT:
|
75
|
map.put(Numbers.Category.TOTAL_AMOUNT, jdbcTemplate.queryForObject(NUMBERS_TOTAL_AMOUNT, Integer.class));
|
76
|
break;
|
77
|
case AVERAGE_AMOUNT:
|
78
|
map.put(Numbers.Category.AVERAGE_AMOUNT, jdbcTemplate.queryForObject(NUMBERS_AVERAGE_AMOUNT, Integer.class));
|
79
|
break;
|
80
|
case AVERAGE_PER_ARTICLE:
|
81
|
map.put(Numbers.Category.AVERAGE_PER_ARTICLE, jdbcTemplate.queryForObject(NUMBERS_AVERAGE_PER_ARTICLE, Integer.class));
|
82
|
break;
|
83
|
case AVERAGE_PER_MONOGRAPH:
|
84
|
map.put(Numbers.Category.AVERAGE_PER_MONOGRAPH, jdbcTemplate.queryForObject(NUMBERS_AVERAGE_PER_MONOGRAPH, Integer.class));
|
85
|
break;
|
86
|
case AVERAGE_PER_BOOK_CHAPTER:
|
87
|
map.put(Numbers.Category.AVERAGE_PER_BOOK_CHAPTER, jdbcTemplate.queryForObject(NUMBERS_AVERAGE_PER_BOOK_CHAPTER, Integer.class));
|
88
|
break;
|
89
|
case PAID_REQUESTS_WITH_DOI:
|
90
|
map.put(Numbers.Category.PAID_REQUESTS_WITH_DOI, jdbcTemplate.queryForObject(NUMBERS_PAID_REQUESTS_WITH_DOI, Integer.class));
|
91
|
break;
|
92
|
case APPROVED_REQUESTS_WITH_DOI:
|
93
|
map.put(Numbers.Category.APPROVED_REQUESTS_WITH_DOI, jdbcTemplate.queryForObject(NUMBERS_APPROVED_REQUESTS_WITH_DOI, Integer.class));
|
94
|
break;
|
95
|
}
|
96
|
}
|
97
|
|
98
|
return new Numbers(map);
|
99
|
}
|
100
|
|
101
|
@Override
|
102
|
public Series getSeries(Series.Category[] categories, Request.RequestStatus[] statuses) {
|
103
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
104
|
Map<Series.Category, List<Quadruple<String, Integer, Float, Float>>> map = new HashMap<Series.Category, List<Quadruple<String, Integer, Float, Float>>>();
|
105
|
|
106
|
for (final Series.Category category:categories) {
|
107
|
String query = null;
|
108
|
|
109
|
switch (category) {
|
110
|
case COUNTRY:
|
111
|
query = SERIES_COUNTRY;
|
112
|
break;
|
113
|
case ORGANIZATION:
|
114
|
query = SERIES_ORGANIZATION;
|
115
|
break;
|
116
|
case PUBLISHER:
|
117
|
query = SERIES_PUBLISHER;
|
118
|
break;
|
119
|
case STATUS:
|
120
|
query = SERIES_STATUS;
|
121
|
break;
|
122
|
case PUBLICATION_TYPE:
|
123
|
query = SERIES_TYPE;
|
124
|
}
|
125
|
|
126
|
if (statuses != null) {
|
127
|
StringBuilder ssb = new StringBuilder();
|
128
|
|
129
|
for (Request.RequestStatus status:statuses) {
|
130
|
String clause;
|
131
|
int code = status.getCode();
|
132
|
|
133
|
switch (code) {
|
134
|
case 0:
|
135
|
clause = " r.status=0";
|
136
|
break;
|
137
|
default:
|
138
|
clause = " (r.status = " + code + ")";
|
139
|
break;
|
140
|
}
|
141
|
|
142
|
ssb.append(ssb.length()==0?clause:" or " + clause);
|
143
|
}
|
144
|
|
145
|
query = query.replace("%WHERE%", " where " + ssb.toString());
|
146
|
} else {
|
147
|
query = query.replace("%WHERE%", "");
|
148
|
}
|
149
|
|
150
|
map.put(category, jdbcTemplate.query(query, new RowMapper<Quadruple<String, Integer, Float, Float>>() {
|
151
|
@Override
|
152
|
public Quadruple<String, Integer, Float, Float> mapRow(ResultSet rs, int rowNum) throws SQLException {
|
153
|
if (category != Series.Category.STATUS)
|
154
|
return new Quadruple<String, Integer, Float, Float>(rs.getString("category"), rs.getInt("count"), rs.getFloat("apc"), rs.getFloat("avgapc"));
|
155
|
else
|
156
|
return new Quadruple<String, Integer, Float, Float>(Request.RequestStatus.forStatus(rs.getInt("category")).getValue(), rs.getInt("count"), rs.getFloat("apc"), rs.getFloat("avgapc"));
|
157
|
}
|
158
|
}));
|
159
|
}
|
160
|
|
161
|
return new Series(map);
|
162
|
}
|
163
|
|
164
|
@Override
|
165
|
public DateSeries getDateSeries(DateSeries.Over over, boolean cumulative, Date from, Date to, String[] publishers, String[] organizations, String[] countries, String[] scientificAreas) {
|
166
|
|
167
|
StringBuilder sb = new StringBuilder();
|
168
|
String dateColumn = null;
|
169
|
String windowKeyword ;
|
170
|
List<String> clauses = new ArrayList<String>();
|
171
|
|
172
|
switch (over) {
|
173
|
case DAY:
|
174
|
dateColumn = "date_trunc('day', submissiondate)";
|
175
|
break;
|
176
|
case MONTH:
|
177
|
dateColumn = "date_trunc('month', submissiondate)";
|
178
|
break;
|
179
|
case YEAR:
|
180
|
dateColumn = "date_trunc('year', submissiondate)";
|
181
|
break;
|
182
|
}
|
183
|
|
184
|
if (cumulative)
|
185
|
windowKeyword = "order";
|
186
|
else
|
187
|
windowKeyword = "partition";
|
188
|
|
189
|
if (from != null) {
|
190
|
clauses.add(" r.submissiondate >= '" + new SimpleDateFormat("yyyy-MM-dd").format(from) + "' ");
|
191
|
}
|
192
|
if (to != null) {
|
193
|
clauses.add(" r.submissiondate <= '" + new SimpleDateFormat("yyyy-MM-dd").format(to) + "' ");
|
194
|
}
|
195
|
|
196
|
if (publishers != null && publishers.length > 0) {
|
197
|
String clause = "pub.id in (";
|
198
|
|
199
|
for (int i = 0; i < publishers.length; i++) {
|
200
|
if (i > 0)
|
201
|
clause += ", ";
|
202
|
|
203
|
clause += "'" + publishers[i] + "'";
|
204
|
}
|
205
|
|
206
|
clause += ")";
|
207
|
|
208
|
clauses.add(clause);
|
209
|
}
|
210
|
|
211
|
if (organizations != null && organizations.length > 0) {
|
212
|
String clause = "o.id in (";
|
213
|
|
214
|
for (int i = 0; i < organizations.length; i++) {
|
215
|
if (i > 0)
|
216
|
clause += ", ";
|
217
|
|
218
|
clause += "'" + organizations[i] + "'";
|
219
|
}
|
220
|
|
221
|
clause += ")";
|
222
|
|
223
|
clauses.add(clause);
|
224
|
}
|
225
|
|
226
|
if (countries != null && countries.length > 0) {
|
227
|
String clause = "c.id in (";
|
228
|
|
229
|
for (int i = 0; i < countries.length; i++) {
|
230
|
if (i > 0)
|
231
|
clause += ", ";
|
232
|
|
233
|
clause += "'" + countries[i] + "'";
|
234
|
}
|
235
|
|
236
|
clause += ")";
|
237
|
|
238
|
clauses.add(clause);
|
239
|
}
|
240
|
|
241
|
if (scientificAreas != null && scientificAreas.length > 0) {
|
242
|
String clause = "p.scientificarea in (";
|
243
|
|
244
|
for (int i = 0; i < scientificAreas.length; i++) {
|
245
|
if (i > 0)
|
246
|
clause += ", ";
|
247
|
|
248
|
clause += "'" + scientificAreas[i] + "'";
|
249
|
}
|
250
|
|
251
|
clause += ")";
|
252
|
|
253
|
clauses.add(clause);
|
254
|
}
|
255
|
|
256
|
sb.append("select distinct ").append(dateColumn).append(" as date, count(r.id) over (").append(windowKeyword).append(" by ").append(dateColumn).append(") as count, sum(apc_paid) over (").append(windowKeyword).append(" by ").append(dateColumn).append(") as apc ");
|
257
|
sb.append("from request r left join project p on r.project=p.id left join organisation o on r.organization=o.id left join country c on c.id=o.country left join (select r.id as rid, p.id, p.name from request r join journal j on r.journal=j.id join publisher p on p.id=j.publisher union select r.id, p.id, p.name from request r join publisher p on r.publisher=p.id) as pub on pub.rid=r.id");
|
258
|
|
259
|
if (clauses.size() > 0)
|
260
|
sb.append(" where ");
|
261
|
|
262
|
for (int i = 0; i < clauses.size(); i++) {
|
263
|
if (i > 0)
|
264
|
sb.append(" and ");
|
265
|
|
266
|
sb.append(" (").append(clauses.get(i)).append(") ");
|
267
|
}
|
268
|
|
269
|
sb.append(" order by ").append(dateColumn);
|
270
|
|
271
|
// System.out.println(sb.toString());return null;
|
272
|
|
273
|
return new DateSeries(new JdbcTemplate(dataSource).query(sb.toString(), new RowMapper<Triple<Date, Integer, Float>>() {
|
274
|
@Override
|
275
|
public Triple<Date, Integer, Float> mapRow(ResultSet rs, int rowNum) throws SQLException {
|
276
|
return new Triple<Date, Integer, Float>(rs.getDate("date"), rs.getInt("count"), rs.getFloat("apc"));
|
277
|
}
|
278
|
}));
|
279
|
}
|
280
|
|
281
|
public static void main(String[] args) {
|
282
|
System.out.println(new StatsManagerImpl().getDateSeries(DateSeries.Over.DAY, true, null,null,null,null,null,null));
|
283
|
}
|
284
|
|
285
|
@Override
|
286
|
public Browse browse(Browse.Category[] categories) {
|
287
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
288
|
Map<Browse.Category, List<Triple<String, String, Integer>>> map = new HashMap<Browse.Category, List<Triple<String, String, Integer>>>();
|
289
|
|
290
|
for (final Browse.Category category:categories) {
|
291
|
String query = null;
|
292
|
|
293
|
switch (category) {
|
294
|
case COUNTRY:
|
295
|
query = BROWSE_COUNTRY;
|
296
|
break;
|
297
|
case ORGANIZATION:
|
298
|
query = BROWSE_ORGANIZATION;
|
299
|
break;
|
300
|
case PUBLISHER:
|
301
|
query = BROWSE_PUBLISHER;
|
302
|
break;
|
303
|
case SCIENTIFIC_AREA:
|
304
|
query = BROWSE_SCIENTIFIC_AREA;
|
305
|
break;
|
306
|
case STATUS:
|
307
|
query = BROWSE_STATUS;
|
308
|
break;
|
309
|
}
|
310
|
|
311
|
map.put(category, jdbcTemplate.query(query, new RowMapper<Triple<String, String, Integer>>() {
|
312
|
@Override
|
313
|
public Triple<String, String, Integer> mapRow(ResultSet rs, int rowNum) throws SQLException {
|
314
|
if (category != Browse.Category.STATUS)
|
315
|
return new Triple<String, String, Integer>(rs.getString("id"), rs.getString("category"), rs.getInt("count"));
|
316
|
else
|
317
|
return new Triple<String, String, Integer>(Request.RequestStatus.forStatus(rs.getInt("id")).name(), Request.RequestStatus.forStatus(rs.getInt("category")).getValue(), rs.getInt("count"));
|
318
|
}
|
319
|
}));
|
320
|
}
|
321
|
|
322
|
return new Browse(map);
|
323
|
}
|
324
|
|
325
|
@Override
|
326
|
public MapData getMapData() {
|
327
|
return null;
|
328
|
}
|
329
|
}
|