Skip to content

Commit a9f81ee

Browse files
committed
wip: database
1 parent d8a4a25 commit a9f81ee

13 files changed

+614
-78
lines changed

packages/util/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
},
3434
"dependencies": {
3535
"@fast-csv/parse": "^5.0.0",
36+
"ip-address": "^9.0.5",
3637
"ky": "^1.7.2",
3738
"yauzl": "^3.1.3"
3839
},

packages/util/src/constants.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { IpLocationApiSettings, LocalDatabase } from './functions/getSettings.js'
2+
3+
export const MAXMIND_URL = 'https://download.maxmind.com/app/geoip_download'
4+
export const DATABASE_SUFFIX_SHA = '.zip.sha256'
5+
export const DATABASE_SUFFIX_ZIP = '.zip'
6+
export const MAIN_FIELDS = ['latitude', 'longitude', 'area', 'postcode'] as const
7+
export const LOCATION_FIELDS = ['country', 'region1', 'region1_name', 'region2', 'region2_name', 'metro', 'timezone', 'city', 'eu'] as const
8+
export const v4: LocalDatabase = {
9+
version: 4,
10+
recordSize: 0,
11+
fileLineMax: 0,
12+
folderLineMax: 0,
13+
}
14+
export const v6: LocalDatabase = {
15+
version: 6,
16+
recordSize: 0,
17+
fileLineMax: 0,
18+
folderLineMax: 0,
19+
}
20+
export const DEFAULT_SETTINGS: IpLocationApiSettings = {
21+
licenseKey: 'redist',
22+
series: 'GeoLite2',
23+
dataDir: '../data',
24+
tmpDataDir: '../tmp',
25+
fields: ['country'],
26+
language: 'en',
27+
smallMemory: false,
28+
smallMemoryFileSize: 4096,
29+
//* Generated settings
30+
fieldDir: '',
31+
dataType: 'Country',
32+
locationFile: false,
33+
mainRecordSize: 2,
34+
locationRecordSize: 0,
35+
v4,
36+
v6,
37+
}

packages/util/src/db.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import type { IpLocationApiInputSettings, IpLocationApiSettings } from './functions/getSettings.js'
22
/* eslint-disable jsdoc/check-param-names */
33
import { existsSync } from 'node:fs'
4-
import { mkdir } from 'node:fs/promises'
4+
import { cp, mkdir, readdir, rename, rm, writeFile } from 'node:fs/promises'
5+
import path from 'node:path'
6+
import { DATABASE_SUFFIX_SHA } from './constants.js'
57
import { createDatabase } from './functions/database/createDatabase.js'
68
import { downloadAndExtractDatabase } from './functions/database/downloadAndExtractDatabase.js'
79
import { getSettings } from './functions/getSettings.js'
@@ -11,18 +13,34 @@ import { getSettings } from './functions/getSettings.js'
1113
* @param inputSettings - Partial settings to override the default ones.
1214
* @returns An array of extracted file names or false if no update was needed.
1315
*/
14-
export async function update(inputSettings?: Partial<IpLocationApiInputSettings>): Promise<false | string[]> {
16+
export async function update(inputSettings?: Partial<IpLocationApiInputSettings>): Promise<void> {
1517
const settings = getSettings(inputSettings)
1618
await ensureDirectoriesExist(settings)
17-
const { files, dataType } = await downloadAndExtractDatabase(settings)
19+
const { files, sha256 } = await downloadAndExtractDatabase(settings)
1820
if (!files)
19-
return false
21+
return
2022

2123
// TODO: Add debug log
22-
await createDatabase(files, settings, dataType)
24+
await createDatabase(files, settings)
2325
// TODO: Add debug log
2426

25-
return files
27+
//* Save the sha256 hash of the database
28+
await writeFile(path.join(settings.fieldDir, `${settings.series}-${settings.dataType}-CSV${DATABASE_SUFFIX_SHA}`), sha256)
29+
30+
//* Rename the temporary files to the correct name
31+
const tmpFiles = (await readdir(settings.fieldDir)).filter(file => file.endsWith('.tmp'))
32+
for (const file of tmpFiles) {
33+
await rename(path.join(settings.fieldDir, file), path.join(settings.fieldDir, file.replace('.tmp', '')))
34+
}
35+
36+
if (settings.smallMemory) {
37+
//* Copy the temporary files to the correct name
38+
await cp(path.join(settings.fieldDir, 'v4-tmp'), path.join(settings.fieldDir, 'v4'), { recursive: true, force: true })
39+
await cp(path.join(settings.fieldDir, 'v6-tmp'), path.join(settings.fieldDir, 'v6'), { recursive: true, force: true })
40+
//* Remove the temporary files
41+
await rm(path.join(settings.fieldDir, 'v4-tmp'), { recursive: true, force: true, maxRetries: 3 })
42+
await rm(path.join(settings.fieldDir, 'v6-tmp'), { recursive: true, force: true, maxRetries: 3 })
43+
}
2644
}
2745

2846
/**

0 commit comments

Comments
 (0)