mirror of https://github.com/bvn13/covid19-ru.git
migrate project to correct database scheme
parent
c22e9c13d8
commit
6e469b2d67
|
@ -30,6 +30,8 @@ subprojects {
|
||||||
fasterxmlJacksonVersion = '2.10.0'
|
fasterxmlJacksonVersion = '2.10.0'
|
||||||
apacheCommonsCollectionsVersion = '4.4'
|
apacheCommonsCollectionsVersion = '4.4'
|
||||||
apacheCommonsLangVersion = '3.9'
|
apacheCommonsLangVersion = '3.9'
|
||||||
|
jsoupVersion = '1.13.1'
|
||||||
|
flywaydbVersion = '6.3.3'
|
||||||
}
|
}
|
||||||
|
|
||||||
group = 'com.bvn13.covid19'
|
group = 'com.bvn13.covid19'
|
||||||
|
|
|
@ -34,8 +34,8 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/")
|
@RequestMapping("/api")
|
||||||
public class MainController {
|
public class ApiController {
|
||||||
|
|
||||||
private final CovidStatsMaker covidStatsMaker;
|
private final CovidStatsMaker covidStatsMaker;
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
package com.bvn13.covid19.api.repositories;
|
package com.bvn13.covid19.api.repositories;
|
||||||
|
|
||||||
import com.bvn13.covid19.model.entities.CovidStat;
|
import com.bvn13.covid19.model.entities.CovidStat;
|
||||||
import com.bvn13.covid19.model.entities.CovidUpdateInfo;
|
import com.bvn13.covid19.model.entities.CovidUpdate;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ import java.util.Collection;
|
||||||
@Repository
|
@Repository
|
||||||
public interface CovidStatsRepository extends JpaRepository<CovidStat, Long> {
|
public interface CovidStatsRepository extends JpaRepository<CovidStat, Long> {
|
||||||
|
|
||||||
Collection<CovidStat> findAllByUpdateInfo(CovidUpdateInfo updateInfo);
|
Collection<CovidStat> findAllByUpdateInfo(CovidUpdate updateInfo);
|
||||||
Collection<CovidStat> findAllByUpdateInfo_Id(long updateInfoId);
|
Collection<CovidStat> findAllByUpdateInfo_Id(long updateInfoId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
package com.bvn13.covid19.api.repositories;
|
package com.bvn13.covid19.api.repositories;
|
||||||
|
|
||||||
import com.bvn13.covid19.api.dtos.CovidUpdateInfoDto;
|
import com.bvn13.covid19.api.dtos.CovidUpdateInfoDto;
|
||||||
import com.bvn13.covid19.model.entities.CovidUpdateInfo;
|
import com.bvn13.covid19.model.entities.CovidUpdate;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
@ -26,11 +26,11 @@ import java.time.LocalDateTime;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface CovidUpdateInfosRepository extends JpaRepository<CovidUpdateInfo, Long> {
|
public interface CovidUpdateInfosRepository extends JpaRepository<CovidUpdate, Long> {
|
||||||
|
|
||||||
@Query("select new com.bvn13.covid19.api.dtos.CovidUpdateInfoDto(max(U.createdOn)) from CovidUpdateInfo U")
|
@Query("select new com.bvn13.covid19.api.dtos.CovidUpdateInfoDto(max(U.createdOn)) from CovidUpdate U")
|
||||||
Optional<CovidUpdateInfoDto> findLastUpdateInfo();
|
Optional<CovidUpdateInfoDto> findLastUpdateInfo();
|
||||||
|
|
||||||
Optional<CovidUpdateInfo> findFirstByCreatedOn(LocalDateTime createdOn);
|
Optional<CovidUpdate> findFirstByCreatedOn(LocalDateTime createdOn);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ package com.bvn13.covid19.api.service;
|
||||||
import com.bvn13.covid19.api.repositories.CovidStatsRepository;
|
import com.bvn13.covid19.api.repositories.CovidStatsRepository;
|
||||||
import com.bvn13.covid19.api.repositories.CovidUpdateInfosRepository;
|
import com.bvn13.covid19.api.repositories.CovidUpdateInfosRepository;
|
||||||
import com.bvn13.covid19.model.entities.CovidStat;
|
import com.bvn13.covid19.model.entities.CovidStat;
|
||||||
import com.bvn13.covid19.model.entities.CovidUpdateInfo;
|
import com.bvn13.covid19.model.entities.CovidUpdate;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -49,7 +49,7 @@ public class CovidStatsMaker {
|
||||||
unless = "#result == null"
|
unless = "#result == null"
|
||||||
)
|
)
|
||||||
@Transactional
|
@Transactional
|
||||||
public Optional<CovidUpdateInfo> findLastUpdateInfo() {
|
public Optional<CovidUpdate> findLastUpdateInfo() {
|
||||||
return updatesRepository.findLastUpdateInfo()
|
return updatesRepository.findLastUpdateInfo()
|
||||||
.flatMap(updateInfo -> updatesRepository.findFirstByCreatedOn(updateInfo.getCreatedOn()));
|
.flatMap(updateInfo -> updatesRepository.findFirstByCreatedOn(updateInfo.getCreatedOn()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
app:
|
app:
|
||||||
zone-id: Europe/Moscow
|
zone-id: Europe/Moscow
|
||||||
|
|
||||||
|
@ -11,6 +14,10 @@ spring:
|
||||||
spec: expireAfterWrite=15m
|
spec: expireAfterWrite=15m
|
||||||
cache-names: covid-last-update-info, covid-stats-by-update-info-id
|
cache-names: covid-last-update-info, covid-stats-by-update-info-id
|
||||||
|
|
||||||
|
flyway:
|
||||||
|
locations: classpath:db/migration
|
||||||
|
schemas: covid
|
||||||
|
|
||||||
datasource:
|
datasource:
|
||||||
driver-class-name: org.postgresql.Driver
|
driver-class-name: org.postgresql.Driver
|
||||||
url: jdbc:postgresql://localhost:5432/covid19
|
url: jdbc:postgresql://localhost:5432/covid19
|
||||||
|
@ -21,10 +28,11 @@ spring:
|
||||||
show-sql: true
|
show-sql: true
|
||||||
hibernate:
|
hibernate:
|
||||||
dialect: org.hibernate.dialect.PostgreSQL
|
dialect: org.hibernate.dialect.PostgreSQL
|
||||||
ddl-auto: update
|
ddl-auto: validate
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
hibernate:
|
hibernate:
|
||||||
|
default_schema: covid
|
||||||
use_sql_comments: true
|
use_sql_comments: true
|
||||||
format_sql: true
|
format_sql: true
|
||||||
show_sql: true
|
show_sql: true
|
||||||
|
@ -46,4 +54,5 @@ logging:
|
||||||
sql:
|
sql:
|
||||||
BasicBinder: trace
|
BasicBinder: trace
|
||||||
pattern:
|
pattern:
|
||||||
console: "%d{dd-MM-yyyy HH:mm:ss.SSS} %highlight(%-5level) %magenta([%thread]) %yellow(%logger.%M) - %msg%n"
|
console: "%d{dd-MM-yyyy HH:mm:ss.SSS} %highlight(%-5level) %magenta([%thread]) %yellow(%logger.%M) - %msg%n"
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@ version = '0.0.1'
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.springframework.boot:spring-boot-starter'
|
implementation 'org.springframework.boot:spring-boot-starter'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-validation'
|
||||||
|
|
||||||
|
runtimeOnly 'org.postgresql:postgresql'
|
||||||
|
implementation 'org.flywaydb:flyway-core'
|
||||||
|
|
||||||
testImplementation 'com.h2database:h2:1.4.194'
|
testImplementation 'com.h2database:h2:1.4.194'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,25 @@
|
||||||
|
/*
|
||||||
|
Copyright [2020] [bvn13]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package com.bvn13.covid19.model;
|
package com.bvn13.covid19.model;
|
||||||
|
|
||||||
import com.bvn13.covid19.model.Covid19ModelConfig;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
//@SpringBootApplication
|
@SpringBootApplication
|
||||||
//@Import({
|
|
||||||
// Covid19ModelConfig.class
|
|
||||||
//})
|
|
||||||
public class Covid19ModelApplication {
|
public class Covid19ModelApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
|
@ -19,7 +19,6 @@ package com.bvn13.covid19.model;
|
||||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan("com.bvn13.covid19.model")
|
@ComponentScan("com.bvn13.covid19.model")
|
||||||
|
|
|
@ -23,11 +23,12 @@ import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "covid_statistics")
|
@Table(schema = "covid", name = "cvd_stats")
|
||||||
public class CovidStat {
|
public class CovidStat {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "cvd_stats_seq")
|
||||||
|
@SequenceGenerator(schema = "covid", name = "cvd_stats_seq", sequenceName = "cvd_stats_seq", allocationSize = 1)
|
||||||
private long id;
|
private long id;
|
||||||
|
|
||||||
private LocalDateTime createdOn;
|
private LocalDateTime createdOn;
|
||||||
|
@ -37,8 +38,8 @@ public class CovidStat {
|
||||||
private Region region;
|
private Region region;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "update_info_id")
|
@JoinColumn(name = "update_id")
|
||||||
private CovidUpdateInfo updateInfo;
|
private CovidUpdate updateInfo;
|
||||||
|
|
||||||
private long sick;
|
private long sick;
|
||||||
private long healed;
|
private long healed;
|
||||||
|
|
|
@ -24,13 +24,14 @@ import java.time.ZonedDateTime;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "update_info", uniqueConstraints = {
|
@Table(schema = "covid", name = "cvd_updates", uniqueConstraints = {
|
||||||
@UniqueConstraint(columnNames = {"createdOn"})
|
@UniqueConstraint(name = "cvd_upd_created_uniq", columnNames = {"createdOn"})
|
||||||
})
|
})
|
||||||
public class CovidUpdateInfo {
|
public class CovidUpdate {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "cvd_updates_seq")
|
||||||
|
@SequenceGenerator(schema = "covid", name = "cvd_updates_seq", sequenceName = "cvd_updates_seq", allocationSize = 1)
|
||||||
private long id;
|
private long id;
|
||||||
|
|
||||||
private LocalDateTime createdOn;
|
private LocalDateTime createdOn;
|
|
@ -18,19 +18,22 @@ package com.bvn13.covid19.model.entities;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.*;
|
||||||
import javax.persistence.Id;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.persistence.UniqueConstraint;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "regions", uniqueConstraints = {
|
@Table(schema = "covid", name = "regions", uniqueConstraints = {
|
||||||
@UniqueConstraint(columnNames = "name")
|
@UniqueConstraint(name = "regions_name_uniq", columnNames = "name")
|
||||||
})
|
})
|
||||||
public class Region {
|
public class Region {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "cvd_regions_seq")
|
||||||
|
@SequenceGenerator(schema = "covid", name = "cvd_regions_seq", sequenceName = "cvd_regions_seq", allocationSize = 1)
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,32 @@
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: covid19-model
|
||||||
|
|
||||||
|
flyway:
|
||||||
|
locations: classpath:db/migration
|
||||||
|
schemas: covid
|
||||||
|
|
||||||
|
|
||||||
|
datasource:
|
||||||
|
driver-class-name: org.postgresql.Driver
|
||||||
|
url: jdbc:postgresql://localhost:5432/covid19
|
||||||
|
username: postgres
|
||||||
|
password: <postgrespass>
|
||||||
|
|
||||||
|
jpa:
|
||||||
|
show-sql: true
|
||||||
|
hibernate:
|
||||||
|
dialect: org.hibernate.dialect.PostgreSQL
|
||||||
|
ddl-auto: none
|
||||||
|
|
||||||
|
properties:
|
||||||
|
hibernate:
|
||||||
|
default_schema: covid
|
||||||
|
use_sql_comments: true
|
||||||
|
format_sql: true
|
||||||
|
show_sql: true
|
||||||
|
jdbc:
|
||||||
|
lob:
|
||||||
|
non_contextual_creation: true
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
--create schema covid;
|
||||||
|
|
||||||
|
create sequence covid.cvd_regions_seq start 1 increment by 1;
|
||||||
|
|
||||||
|
create table covid.regions
|
||||||
|
(
|
||||||
|
id bigint not null default nextval('covid.cvd_regions_seq')
|
||||||
|
constraint regions_pkey primary key,
|
||||||
|
name varchar(255) not null
|
||||||
|
constraint regions_name_uniq unique
|
||||||
|
);
|
||||||
|
|
||||||
|
alter sequence covid.cvd_regions_seq owned by covid.regions.id;
|
||||||
|
alter sequence covid.cvd_regions_seq owner to covid19;
|
||||||
|
alter table covid.regions owner to covid19;
|
||||||
|
|
||||||
|
create sequence covid.cvd_updates_seq start 1 increment by 1;
|
||||||
|
|
||||||
|
create table covid.cvd_updates
|
||||||
|
(
|
||||||
|
id bigint not null default nextval('covid.cvd_updates_seq')
|
||||||
|
constraint cvd_updates_pkey primary key,
|
||||||
|
created_on timestamp
|
||||||
|
constraint cvd_upd_created_uniq unique,
|
||||||
|
datetime timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
alter sequence covid.cvd_updates_seq owned by covid.cvd_updates.id;
|
||||||
|
alter sequence covid.cvd_updates_seq owner to covid19;
|
||||||
|
alter table covid.cvd_updates owner to covid19;
|
||||||
|
|
||||||
|
create sequence covid.cvd_stats_seq start 1 increment by 1;
|
||||||
|
|
||||||
|
create table if not exists covid.cvd_stats
|
||||||
|
(
|
||||||
|
id bigint not null default nextval('covid.cvd_stats_seq')
|
||||||
|
constraint cvd_stats_pkey primary key,
|
||||||
|
created_on timestamp,
|
||||||
|
died bigint not null,
|
||||||
|
healed bigint not null,
|
||||||
|
sick bigint not null,
|
||||||
|
region_id bigint
|
||||||
|
constraint fk_cvd_stats_region references covid.regions,
|
||||||
|
update_id bigint
|
||||||
|
constraint fk_cvd_stats_updates references covid.cvd_updates
|
||||||
|
);
|
||||||
|
|
||||||
|
alter sequence covid.cvd_stats_seq owned by covid.cvd_stats.id;
|
||||||
|
alter sequence covid.cvd_stats_seq owner to covid19;
|
||||||
|
alter table covid_statistics owner to covid19;
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
insert into covid.regions(id, name) VALUES
|
||||||
|
('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', 'Ненецкий автономный округ');
|
||||||
|
|
||||||
|
insert into covid.cvd_updates(created_on, datetime)
|
||||||
|
SELECT u.created_on, u.datetime from public.update_info u;
|
||||||
|
|
||||||
|
insert into covid.cvd_stats(region_id, created_on, sick, healed, died, update_id)
|
||||||
|
select r.id,
|
||||||
|
s.created_on,
|
||||||
|
s.sick,
|
||||||
|
s.healed,
|
||||||
|
s.died,
|
||||||
|
u_new.id
|
||||||
|
from public.covid_statistics as s
|
||||||
|
inner join covid.regions as r
|
||||||
|
on s.region_id = r.name
|
||||||
|
inner join public.update_info as u_old
|
||||||
|
on u_old.id = s.update_info_id
|
||||||
|
inner join covid.cvd_updates as u_new
|
||||||
|
on u_new.datetime = u_old.datetime;
|
|
@ -6,10 +6,15 @@ dependencies {
|
||||||
compile(project(':covid19-model'))
|
compile(project(':covid19-model'))
|
||||||
|
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||||
implementation 'org.apache.camel.springboot:camel-spring-boot-starter:3.1.0'
|
implementation "org.apache.camel.springboot:camel-spring-boot-starter:${camelVersion}"
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||||
|
|
||||||
implementation 'org.jsoup:jsoup:1.13.1'
|
compileOnly "org.springframework.boot:spring-boot-configuration-processor:${springBootVersion}"
|
||||||
|
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor:${springBootVersion}"
|
||||||
|
|
||||||
|
implementation "org.jsoup:jsoup:${jsoupVersion}"
|
||||||
|
|
||||||
|
implementation "org.apache.camel:camel-mail:${camelVersion}"
|
||||||
|
|
||||||
runtimeOnly 'org.postgresql:postgresql'
|
runtimeOnly 'org.postgresql:postgresql'
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,10 @@ limitations under the License.
|
||||||
package com.bvn13.covid19.scheduler;
|
package com.bvn13.covid19.scheduler;
|
||||||
|
|
||||||
import com.bvn13.covid19.model.Covid19ModelConfig;
|
import com.bvn13.covid19.model.Covid19ModelConfig;
|
||||||
|
import com.bvn13.covid19.scheduler.updater.stopcoronovirusrf.MailConfig;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
|
||||||
|
@ -27,6 +29,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
@Import({
|
@Import({
|
||||||
Covid19ModelConfig.class
|
Covid19ModelConfig.class
|
||||||
})
|
})
|
||||||
|
@EnableConfigurationProperties(MailConfig.class)
|
||||||
public class Covid19SchedulerApplication {
|
public class Covid19SchedulerApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
|
@ -16,10 +16,10 @@ limitations under the License.
|
||||||
|
|
||||||
package com.bvn13.covid19.scheduler;
|
package com.bvn13.covid19.scheduler;
|
||||||
|
|
||||||
import com.bvn13.covid19.model.entities.CovidUpdateInfo;
|
import com.bvn13.covid19.model.entities.CovidUpdate;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface CovidUpdateInfosRepository extends JpaRepository<CovidUpdateInfo, Long> {
|
public interface CovidUpdateInfosRepository extends JpaRepository<CovidUpdate, Long> {
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
Copyright [2020] [bvn13]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.bvn13.covid19.scheduler.updater.stopcoronovirusrf;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Max;
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "app.mail")
|
||||||
|
public class MailConfig {
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private String username;
|
||||||
|
@NotBlank
|
||||||
|
private String password;
|
||||||
|
@NotBlank
|
||||||
|
private String host;
|
||||||
|
@Min(1)
|
||||||
|
@Max(65536)
|
||||||
|
private int port;
|
||||||
|
@NotBlank
|
||||||
|
private String sender;
|
||||||
|
@NotBlank
|
||||||
|
private String recipient;
|
||||||
|
@NotBlank
|
||||||
|
private String subject;
|
||||||
|
|
||||||
|
public String constructEndpoint() {
|
||||||
|
return "smtp://" + host + ":" + port +
|
||||||
|
"?username=" + username +
|
||||||
|
"&password=" + password +
|
||||||
|
"&from=" + sender +
|
||||||
|
"&to=" + recipient +
|
||||||
|
"&subject=" + subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,11 +17,11 @@ limitations under the License.
|
||||||
package com.bvn13.covid19.scheduler.updater.stopcoronovirusrf;
|
package com.bvn13.covid19.scheduler.updater.stopcoronovirusrf;
|
||||||
|
|
||||||
import com.bvn13.covid19.model.entities.CovidStat;
|
import com.bvn13.covid19.model.entities.CovidStat;
|
||||||
|
import com.bvn13.covid19.model.entities.CovidUpdate;
|
||||||
import com.bvn13.covid19.model.entities.Region;
|
import com.bvn13.covid19.model.entities.Region;
|
||||||
import com.bvn13.covid19.model.entities.CovidUpdateInfo;
|
|
||||||
import com.bvn13.covid19.scheduler.CovidStatsRepository;
|
import com.bvn13.covid19.scheduler.CovidStatsRepository;
|
||||||
import com.bvn13.covid19.scheduler.RegionsRepository;
|
|
||||||
import com.bvn13.covid19.scheduler.CovidUpdateInfosRepository;
|
import com.bvn13.covid19.scheduler.CovidUpdateInfosRepository;
|
||||||
|
import com.bvn13.covid19.scheduler.RegionsRepository;
|
||||||
import com.bvn13.covid19.scheduler.updater.stopcoronovirusrf.model.RowData;
|
import com.bvn13.covid19.scheduler.updater.stopcoronovirusrf.model.RowData;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
@ -33,7 +33,6 @@ import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -59,31 +58,10 @@ public class StopcoronovirusRfService {
|
||||||
@Transactional
|
@Transactional
|
||||||
public void saveRawData(String date, Collection<RowData> rawData) {
|
public void saveRawData(String date, Collection<RowData> rawData) {
|
||||||
|
|
||||||
ZonedDateTime zdt = parseZonedDateTime(date);
|
ZonedDateTime dateOfData = parseZonedDateTime(date);
|
||||||
|
CovidUpdate updateInfo = createUpdateInfo(dateOfData);
|
||||||
CovidUpdateInfo updateInfo = new CovidUpdateInfo();
|
for (RowData row : rawData) {
|
||||||
updateInfo.setCreatedOn(LocalDateTime.now());
|
repository.save(createStats(row, updateInfo));
|
||||||
updateInfo.setDatetime(zdt);
|
|
||||||
updateInfo = updatesRepository.save(updateInfo);
|
|
||||||
|
|
||||||
Iterator<RowData> iter = rawData.iterator();
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
RowData row = iter.next();
|
|
||||||
|
|
||||||
Region region = regionsRepository.findByName(row.getRegion()).orElseGet(() -> {
|
|
||||||
Region r = new Region();
|
|
||||||
r.setName(row.getRegion());
|
|
||||||
return regionsRepository.save(r);
|
|
||||||
});
|
|
||||||
|
|
||||||
CovidStat covidStat = new CovidStat();
|
|
||||||
covidStat.setUpdateInfo(updateInfo);
|
|
||||||
covidStat.setRegion(region);
|
|
||||||
covidStat.setSick(Long.parseLong(row.getSick()));
|
|
||||||
covidStat.setHealed(Long.parseLong(row.getHealed()));
|
|
||||||
covidStat.setDied(Long.parseLong(row.getDied()));
|
|
||||||
|
|
||||||
repository.save(covidStat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -104,6 +82,31 @@ public class StopcoronovirusRfService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CovidUpdate createUpdateInfo(ZonedDateTime dateOfData) {
|
||||||
|
CovidUpdate updateInfo = new CovidUpdate();
|
||||||
|
updateInfo.setCreatedOn(LocalDateTime.now());
|
||||||
|
updateInfo.setDatetime(dateOfData);
|
||||||
|
return updatesRepository.save(updateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Region detectRegion(String region) {
|
||||||
|
return regionsRepository.findByName(region).orElseGet(() -> {
|
||||||
|
Region r = new Region();
|
||||||
|
r.setName(region);
|
||||||
|
return regionsRepository.save(r);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private CovidStat createStats(RowData row, CovidUpdate updateInfo) {
|
||||||
|
CovidStat covidStat = new CovidStat();
|
||||||
|
covidStat.setUpdateInfo(updateInfo);
|
||||||
|
covidStat.setRegion(detectRegion(row.getRegion()));
|
||||||
|
covidStat.setSick(Long.parseLong(row.getSick()));
|
||||||
|
covidStat.setHealed(Long.parseLong(row.getHealed()));
|
||||||
|
covidStat.setDied(Long.parseLong(row.getDied()));
|
||||||
|
return covidStat;
|
||||||
|
}
|
||||||
|
|
||||||
private int detectMonth(String m) {
|
private int detectMonth(String m) {
|
||||||
switch (m.trim().toLowerCase()) {
|
switch (m.trim().toLowerCase()) {
|
||||||
case "январь":
|
case "январь":
|
||||||
|
|
|
@ -19,7 +19,10 @@ package com.bvn13.covid19.scheduler.updater.stopcoronovirusrf;
|
||||||
import com.bvn13.covid19.scheduler.updater.stopcoronovirusrf.model.RowData;
|
import com.bvn13.covid19.scheduler.updater.stopcoronovirusrf.model.RowData;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.camel.*;
|
import org.apache.camel.Body;
|
||||||
|
import org.apache.camel.Handler;
|
||||||
|
import org.apache.camel.Header;
|
||||||
|
import org.apache.camel.LoggingLevel;
|
||||||
import org.apache.camel.builder.RouteBuilder;
|
import org.apache.camel.builder.RouteBuilder;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -36,12 +39,12 @@ public class StopcoronovirusRfUpdater extends RouteBuilder {
|
||||||
|
|
||||||
private final StopcoronovirusRfDataRetriever dataRetriever;
|
private final StopcoronovirusRfDataRetriever dataRetriever;
|
||||||
private final StopcoronovirusRfService service;
|
private final StopcoronovirusRfService service;
|
||||||
|
private final MailConfig mailConfig;
|
||||||
|
|
||||||
@Value("${app.timer.stopcoronovirusrf}")
|
@Value("${app.timer.stopcoronovirusrf}")
|
||||||
private int stopcoronovirusrfTimerSecons;
|
private int stopcoronovirusrfTimerSecons;
|
||||||
private long stopcoronovirusrfTimerMillis;
|
private long stopcoronovirusrfTimerMillis;
|
||||||
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
stopcoronovirusrfTimerMillis = stopcoronovirusrfTimerSecons * 1000;
|
stopcoronovirusrfTimerMillis = stopcoronovirusrfTimerSecons * 1000;
|
||||||
|
@ -50,6 +53,9 @@ public class StopcoronovirusRfUpdater extends RouteBuilder {
|
||||||
@Override
|
@Override
|
||||||
public void configure() throws Exception {
|
public void configure() throws Exception {
|
||||||
|
|
||||||
|
onException(RuntimeException.class)
|
||||||
|
.to(mailConfig.constructEndpoint());
|
||||||
|
|
||||||
from("timer:stopcoronovirusrf?delay=1000&period="+stopcoronovirusrfTimerMillis)
|
from("timer:stopcoronovirusrf?delay=1000&period="+stopcoronovirusrfTimerMillis)
|
||||||
.log(LoggingLevel.DEBUG, log, "Start retrieving data from stopcoronovirus.rf")
|
.log(LoggingLevel.DEBUG, log, "Start retrieving data from stopcoronovirus.rf")
|
||||||
.process(dataRetriever::retrieveData)
|
.process(dataRetriever::retrieveData)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
|
||||||
app:
|
app:
|
||||||
user-agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0
|
user-agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0
|
||||||
zone-id: Europe/Moscow
|
zone-id: Europe/Moscow
|
||||||
|
@ -5,11 +8,21 @@ app:
|
||||||
# IN SECONDS
|
# IN SECONDS
|
||||||
# 1 hour
|
# 1 hour
|
||||||
stopcoronovirusrf: 3600
|
stopcoronovirusrf: 3600
|
||||||
|
mail:
|
||||||
|
username: <mail-username>
|
||||||
|
password: <mail-password>
|
||||||
|
host: smtp.yandex.ru
|
||||||
|
port: 465
|
||||||
|
to: <your-password>
|
||||||
|
subject: Ошибка загрузки данных COVID19
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: covid19-scheduler
|
name: covid19-scheduler
|
||||||
|
|
||||||
|
flyway:
|
||||||
|
locations: classpath:db/migration
|
||||||
|
schemas: covid
|
||||||
|
|
||||||
datasource:
|
datasource:
|
||||||
driver-class-name: org.postgresql.Driver
|
driver-class-name: org.postgresql.Driver
|
||||||
|
@ -21,10 +34,11 @@ spring:
|
||||||
show-sql: true
|
show-sql: true
|
||||||
hibernate:
|
hibernate:
|
||||||
dialect: org.hibernate.dialect.PostgreSQL
|
dialect: org.hibernate.dialect.PostgreSQL
|
||||||
ddl-auto: update
|
ddl-auto: validate
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
hibernate:
|
hibernate:
|
||||||
|
default_schema: covid
|
||||||
use_sql_comments: true
|
use_sql_comments: true
|
||||||
format_sql: true
|
format_sql: true
|
||||||
show_sql: true
|
show_sql: true
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
Loading…
Reference in New Issue