feat: postgres reverse geocoding (#5301)

* feat: add system metadata repository for storing key values for internal usage

* feat: add database entities for geodata

* feat: move reverse geocoding from local-reverse-geocoder to postgresql

* infra: disable synchronization for geodata_places table until typeorm supports earth column

* feat: remove cities override config as we will default all instances to cities500 now

* test: e2e tests don't clear geodata tables on reset
This commit is contained in:
Zack Pollard
2023-11-25 18:53:30 +00:00
committed by GitHub
parent 0108211c0f
commit 698226634e
46 changed files with 368 additions and 645 deletions
@@ -0,0 +1,10 @@
import { Column, Entity, PrimaryColumn } from 'typeorm';
@Entity('geodata_admin1')
export class GeodataAdmin1Entity {
@PrimaryColumn({ type: 'varchar' })
key!: string;
@Column({ type: 'varchar' })
name!: string;
}
@@ -0,0 +1,10 @@
import { Column, Entity, PrimaryColumn } from 'typeorm';
@Entity('geodata_admin2')
export class GeodataAdmin2Entity {
@PrimaryColumn({ type: 'varchar' })
key!: string;
@Column({ type: 'varchar' })
name!: string;
}
@@ -0,0 +1,59 @@
import { GeodataAdmin1Entity } from '@app/infra/entities/geodata-admin1.entity';
import { GeodataAdmin2Entity } from '@app/infra/entities/geodata-admin2.entity';
import { Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
@Entity('geodata_places', { synchronize: false })
export class GeodataPlacesEntity {
@PrimaryColumn({ type: 'integer' })
id!: number;
@Column({ type: 'varchar', length: 200 })
name!: string;
@Column({ type: 'float' })
longitude!: number;
@Column({ type: 'float' })
latitude!: number;
// @Column({
// generatedType: 'STORED',
// asExpression: 'll_to_earth((latitude)::double precision, (longitude)::double precision)',
// type: 'earth',
// })
earthCoord!: unknown;
@Column({ type: 'char', length: 2 })
countryCode!: string;
@Column({ type: 'varchar', length: 20, nullable: true })
admin1Code!: string;
@Column({ type: 'varchar', length: 80, nullable: true })
admin2Code!: string;
@Column({
type: 'varchar',
generatedType: 'STORED',
asExpression: `"countryCode" || '.' || "admin1Code"`,
nullable: true,
})
admin1Key!: string;
@ManyToOne(() => GeodataAdmin1Entity, { eager: true, nullable: true, createForeignKeyConstraints: false })
admin1!: GeodataAdmin1Entity;
@Column({
type: 'varchar',
generatedType: 'STORED',
asExpression: `"countryCode" || '.' || "admin1Code" || '.' || "admin2Code"`,
nullable: true,
})
admin2Key!: string;
@ManyToOne(() => GeodataAdmin2Entity, { eager: true, nullable: true, createForeignKeyConstraints: false })
admin2!: GeodataAdmin2Entity;
@Column({ type: 'date' })
modificationDate!: Date;
}
+12
View File
@@ -1,3 +1,4 @@
import { GeodataAdmin2Entity } from '@app/infra/entities/geodata-admin2.entity';
import { ActivityEntity } from './activity.entity';
import { AlbumEntity } from './album.entity';
import { APIKeyEntity } from './api-key.entity';
@@ -6,6 +7,8 @@ import { AssetJobStatusEntity } from './asset-job-status.entity';
import { AssetEntity } from './asset.entity';
import { AuditEntity } from './audit.entity';
import { ExifEntity } from './exif.entity';
import { GeodataAdmin1Entity } from './geodata-admin1.entity';
import { GeodataPlacesEntity } from './geodata-places.entity';
import { LibraryEntity } from './library.entity';
import { MoveEntity } from './move.entity';
import { PartnerEntity } from './partner.entity';
@@ -13,6 +16,7 @@ import { PersonEntity } from './person.entity';
import { SharedLinkEntity } from './shared-link.entity';
import { SmartInfoEntity } from './smart-info.entity';
import { SystemConfigEntity } from './system-config.entity';
import { SystemMetadataEntity } from './system-metadata.entity';
import { TagEntity } from './tag.entity';
import { UserTokenEntity } from './user-token.entity';
import { UserEntity } from './user.entity';
@@ -25,6 +29,9 @@ export * from './asset-job-status.entity';
export * from './asset.entity';
export * from './audit.entity';
export * from './exif.entity';
export * from './geodata-admin1.entity';
export * from './geodata-admin2.entity';
export * from './geodata-places.entity';
export * from './library.entity';
export * from './move.entity';
export * from './partner.entity';
@@ -32,6 +39,7 @@ export * from './person.entity';
export * from './shared-link.entity';
export * from './smart-info.entity';
export * from './system-config.entity';
export * from './system-metadata.entity';
export * from './tag.entity';
export * from './user-token.entity';
export * from './user.entity';
@@ -45,12 +53,16 @@ export const databaseEntities = [
AssetJobStatusEntity,
AuditEntity,
ExifEntity,
GeodataPlacesEntity,
GeodataAdmin1Entity,
GeodataAdmin2Entity,
MoveEntity,
PartnerEntity,
PersonEntity,
SharedLinkEntity,
SmartInfoEntity,
SystemConfigEntity,
SystemMetadataEntity,
TagEntity,
UserEntity,
UserTokenEntity,
@@ -66,7 +66,6 @@ export enum SystemConfigKey {
MAP_DARK_STYLE = 'map.darkStyle',
REVERSE_GEOCODING_ENABLED = 'reverseGeocoding.enabled',
REVERSE_GEOCODING_CITIES_FILE_OVERRIDE = 'reverseGeocoding.citiesFileOverride',
NEW_VERSION_CHECK_ENABLED = 'newVersionCheck.enabled',
@@ -145,13 +144,6 @@ export enum Colorspace {
P3 = 'p3',
}
export enum CitiesFile {
CITIES_15000 = 'cities15000',
CITIES_5000 = 'cities5000',
CITIES_1000 = 'cities1000',
CITIES_500 = 'cities500',
}
export interface SystemConfig {
ffmpeg: {
crf: number;
@@ -200,7 +192,6 @@ export interface SystemConfig {
};
reverseGeocoding: {
enabled: boolean;
citiesFileOverride: CitiesFile;
};
oauth: {
enabled: boolean;
@@ -0,0 +1,18 @@
import { Column, Entity, PrimaryColumn } from 'typeorm';
@Entity('system_metadata')
export class SystemMetadataEntity {
@PrimaryColumn()
key!: string;
@Column({ type: 'jsonb', default: '{}', transformer: { to: JSON.stringify, from: JSON.parse } })
value!: { [key: string]: unknown };
}
export enum SystemMetadataKey {
REVERSE_GEOCODING_STATE = 'reverse-geocoding-state',
}
export interface SystemMetadata extends Record<SystemMetadataKey, { [key: string]: unknown }> {
[SystemMetadataKey.REVERSE_GEOCODING_STATE]: { lastUpdate?: string; lastImportFileName?: string };
}