234 | | |
| 234 | На јавната страница /results достапни се податоци за резултатите од тековни и минати реализации со можност за филтрирање по реализации, општини и/или гласачки места. Очекувано, при реално користење оваа функционалност би била најкористена и најоптоварена, а истовремено повлекува големо количество податоци, односно податоци за сите гласови, кандидатури, избирачки места и слично. Со цел да направиме пооптимално решение, оваа го имплементиравме на начин што во базата е креирана функција којашто при креирање реализација креира материјализирани погледи за резултатите по општини и по избирачки места. На овој начин, обезбедуваме при освежување на погледот, соодветно да се освежи само погледот за моменталната реализација, без притоа да трошиме ресурси за агрегација на резултатите од претходни реализации, како и да не го оптоваруваме погледот со дополнителен, голем број редици. |
| 235 | {{{#!java |
| 236 | create or replace function public.create_view_for_candidates_realizations() |
| 237 | returns trigger |
| 238 | language plpgsql |
| 239 | as |
| 240 | $$ |
| 241 | declare |
| 242 | view_name text; |
| 243 | begin |
| 244 | |
| 245 | view_name := format('results_per_polling_stations_%s', new.ri_id); |
| 246 | raise notice '%', view_name; |
| 247 | execute format('create materialized view if not exists %I as |
| 248 | ( |
| 249 | select ri.ri_id, k.kan_id, gl.im_id, count(distinct gk.gl_id) |
| 250 | from realizacii_na_izbori ri |
| 251 | join realizacii_so_kandidaturi rk on ri.ri_id = rk.ri_id |
| 252 | left join kandidaturi k on rk.ri_id = k.ri_id |
| 253 | left join glasovi_za_kandidat gk on k.kan_id = gk.kan_id |
| 254 | left join kandidati kan on kan.g_id = k.g_id |
| 255 | left join gragjani g on k.g_id = g.g_id |
| 256 | left join glasovi gl on gk.gl_id = gl.gl_id |
| 257 | where ri.ri_id = %s |
| 258 | group by ri.ri_id, k.kan_id, kan.g_id, gl.im_id |
| 259 | );', view_name, new.ri_id); |
| 260 | |
| 261 | view_name := format('results_per_municipalities_%s', new.ri_id); |
| 262 | raise notice '%', view_name; |
| 263 | execute format('create materialized view if not exists %I as |
| 264 | ( |
| 265 | select gk.kan_id, o.o_id, ri.ri_id, count(distinct gk.gl_id) |
| 266 | from glasovi gl |
| 267 | join glasovi_za_kandidat gk on gl.gl_id = gk.gl_id |
| 268 | join izbiracki_mesta im on gl.im_id = im.im_id |
| 269 | join adresi a on im.a_id = a.a_id |
| 270 | join opstini o on a.o_id = o.o_id |
| 271 | join realizacii_na_izbori ri on gl.ri_id = ri.ri_id |
| 272 | where ri.ri_id = %s |
| 273 | group by gk.kan_id, o.o_id, ri.ri_id |
| 274 | );', view_name, new.ri_id); |
| 275 | |
| 276 | return new; |
| 277 | end; |
| 278 | $$; |
| 279 | }}} |
| 280 | {{{#!java |
| 281 | create or replace function public.create_view_for_lists_realizations() |
| 282 | returns trigger |
| 283 | language plpgsql |
| 284 | as |
| 285 | $$ |
| 286 | declare |
| 287 | view_name text; |
| 288 | begin |
| 289 | |
| 290 | view_name := format('lists_results_per_polling_stations_%s', new.ri_id); |
| 291 | raise notice '%', view_name; |
| 292 | execute format('create materialized view if not exists %I as |
| 293 | ( |
| 294 | select kl.kl_id, gl.im_id, ri.ri_id, count(distinct gli.gl_id) |
| 295 | from glasovi gl |
| 296 | join glasovi_za_lista gli on gl.gl_id = gli.gl_id |
| 297 | join kandidatski_listi kl on gli.kl_id = kl.kl_id |
| 298 | join izbiracki_mesta im on gl.im_id = im.im_id |
| 299 | join realizacii_na_izbori ri on gl.ri_id = ri.ri_id |
| 300 | where ri.ri_id = %s |
| 301 | group by kl.kl_id, gl.im_id, ri.ri_id);', view_name, new.ri_id); |
| 302 | |
| 303 | view_name := format('lists_results_per_municipalities_%s', new.ri_id); |
| 304 | raise notice '%', view_name; |
| 305 | execute format('create materialized view if not exists %I as |
| 306 | ( |
| 307 | select kl.kl_id, o.o_id, ri.ri_id, count(distinct gli.gl_id) |
| 308 | from glasovi gl |
| 309 | join glasovi_za_lista gli on gl.gl_id = gli.gl_id |
| 310 | join kandidatski_listi kl on gli.kl_id = kl.kl_id |
| 311 | join izbiracki_mesta im on gl.im_id = im.im_id |
| 312 | join adresi a on im.a_id = a.a_id |
| 313 | join opstini o on a.o_id = o.o_id |
| 314 | join realizacii_na_izbori ri on gl.ri_id = ri.ri_id |
| 315 | where ri.ri_id = %s |
| 316 | group by kl.kl_id, o.o_id, ri.ri_id |
| 317 | );', view_name, new.ri_id); |
| 318 | |
| 319 | return new; |
| 320 | end; |
| 321 | $$; |
| 322 | |
| 323 | }}} |
| 324 | Кога корисникот ќе пристапи до страницата за резултати, наместо во моментот да се изврши прашалник со агрегативни функции, преку Spring Data JPA се повикува друга функција во базата, која врз основа на идентификаторот на реализацијата ги враќа резултатите од соодветниот поглед. Вака добиените резултати, понатаму се мапираат во DTO објект кој служи за нивно прикажување на страница. |
| 325 | {{{#! |
| 326 | create or replace function public.get_view_for_candidates_realizations(real_id bigint) |
| 327 | returns table(ri_id bigint, kan_id bigint, im_id bigint, vote_count bigint) |
| 328 | language plpgsql |
| 329 | as |
| 330 | $$ |
| 331 | declare |
| 332 | view_name text; |
| 333 | result record; |
| 334 | begin |
| 335 | |
| 336 | view_name := format('results_per_polling_stations_%s', real_id); |
| 337 | raise notice '%', view_name; |
| 338 | return query execute format('SELECT * FROM %s', view_name); |
| 339 | end; |
| 340 | $$; |
| 341 | }}} |
| 342 | {{#! |
| 343 | create or replace function public.get_view_for_lists_realizations(real_id bigint) |
| 344 | returns table(kl_id bigint, ri_id bigint, im_id bigint, vote_count bigint) |
| 345 | language plpgsql |
| 346 | as |
| 347 | $$ |
| 348 | declare |
| 349 | view_name text; |
| 350 | result record; |
| 351 | begin |
| 352 | |
| 353 | view_name := format('lists_results_per_polling_stations_%s', real_id); |
| 354 | raise notice '%', view_name; |
| 355 | return query execute format('SELECT * FROM %s', view_name); |
| 356 | end; |
| 357 | $$; |
| 358 | |
| 359 | }}} |
| 360 | {{{#!java |
| 361 | create or replace function public.get_view_for_candidates_realizations_by_municipalities(real_id bigint) |
| 362 | returns table(kan_id bigint, o_id bigint, ri_id bigint, vote_count bigint) |
| 363 | language plpgsql |
| 364 | as |
| 365 | $$ |
| 366 | declare |
| 367 | view_name text; |
| 368 | result record; |
| 369 | begin |
| 370 | |
| 371 | view_name := format('results_per_municipalities_%s', real_id); |
| 372 | raise notice '%', view_name; |
| 373 | return query execute format('SELECT * FROM %s', view_name); |
| 374 | end; |
| 375 | $$; |
| 376 | }}} |
| 377 | {{{#!java |
| 378 | create or replace function public.get_view_for_lists_realizations_by_municipalities(real_id bigint) |
| 379 | returns table(gl_id bigint, o_id bigint, ri_id bigint, vote_count bigint) |
| 380 | language plpgsql |
| 381 | as |
| 382 | $$ |
| 383 | declare |
| 384 | view_name text; |
| 385 | result record; |
| 386 | begin |
| 387 | |
| 388 | view_name := format('lists_results_per_municipalities_%s', real_id); |
| 389 | raise notice '%', view_name; |
| 390 | return query execute format('SELECT * FROM %s', view_name); |
| 391 | end; |
| 392 | $$; |
| 393 | }}} |
| 394 | Притоа, во соодветни приватни функции од ResultsService-от се врши мапирањето на следниот начин и кон view-то се враќа објектот за репрезентација. |
| 395 | {{{#! |
| 396 | List<TotalListResultsPerPollingStation> listResultsPerPollingStation(Long realizationId, Long pollingStationId) { |
| 397 | List<Map<String, Object>> results = turnoutRepository.totalListResultsPerPollingStation(realizationId, pollingStationId); |
| 398 | return results.stream().map(x -> { |
| 399 | TotalListResultsPerPollingStation totalListResultsPerPollingStation = new TotalListResultsPerPollingStation(); |
| 400 | totalListResultsPerPollingStation.setListName((x.get("list_name").toString())); |
| 401 | totalListResultsPerPollingStation.setPartyName((String) x.get("participant").toString()); |
| 402 | totalListResultsPerPollingStation.setVoteCount((String) x.get("vote_count").toString()); |
| 403 | totalListResultsPerPollingStation.setPollingStationId((String) x.get("polling_station_id").toString()); |
| 404 | return totalListResultsPerPollingStation; |
| 405 | }).toList(); |
| 406 | } |
| 407 | }}} |