@socialgouv/matomo-postgres 2.4.3 → 2.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,7 @@ import { FileMigrationProvider, Migrator } from 'kysely';
12
12
  import * as path from 'path';
13
13
  import { MATOMO_TABLE_NAME } from './config.js';
14
14
  import { db } from './db.js';
15
+ import { syncDestinationTableSchema } from './syncDestinationTableSchema.js';
15
16
  function migrateToLatest() {
16
17
  return __awaiter(this, void 0, void 0, function* () {
17
18
  console.log(`Starting migrate to latest`);
@@ -44,6 +45,7 @@ function migrateToLatest() {
44
45
  else if (!(results === null || results === void 0 ? void 0 : results.length)) {
45
46
  console.log('No migration to run');
46
47
  }
48
+ yield syncDestinationTableSchema(db);
47
49
  }
48
50
  catch (uncaughtError) {
49
51
  console.error('UNCAUGHT ERROR during migration:');
@@ -0,0 +1,47 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { sql } from 'kysely';
11
+ import { DESTINATION_TABLE, MATOMO_TABLE_NAME, PARTITIONED_MATOMO_TABLE_NAME } from './config.js';
12
+ // Kysely migrations operate on MATOMO_TABLE_NAME (default `matomo`), but
13
+ // several deployments run multiple cronjobs against a single database with
14
+ // distinct DESTINATION_TABLEs (matomo_back, matomo_app, matomo_landing, ...).
15
+ // Schema changes applied to `matomo` never reach those custom destinations,
16
+ // and INSERTs fail with `column "..." does not exist`. After running the
17
+ // regular migrations, mirror any missing columns from MATOMO_TABLE_NAME onto
18
+ // DESTINATION_TABLE so writes stay schema-compatible.
19
+ export function syncDestinationTableSchema(db) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ if (DESTINATION_TABLE === MATOMO_TABLE_NAME ||
22
+ DESTINATION_TABLE === PARTITIONED_MATOMO_TABLE_NAME) {
23
+ return;
24
+ }
25
+ const { rows } = yield sql `
26
+ SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS coltype
27
+ FROM pg_attribute a
28
+ WHERE a.attrelid = ${MATOMO_TABLE_NAME}::regclass
29
+ AND a.attnum > 0
30
+ AND NOT a.attisdropped
31
+ AND NOT EXISTS (
32
+ SELECT 1 FROM pg_attribute b
33
+ WHERE b.attrelid = ${DESTINATION_TABLE}::regclass
34
+ AND b.attname = a.attname
35
+ AND b.attnum > 0
36
+ AND NOT b.attisdropped
37
+ )
38
+ `.execute(db);
39
+ for (const { attname, coltype } of rows) {
40
+ console.log(`Syncing schema: adding column "${attname}" ${coltype} to ${DESTINATION_TABLE}`);
41
+ yield sql `
42
+ ALTER TABLE ${sql.id(DESTINATION_TABLE)}
43
+ ADD COLUMN ${sql.id(attname)} ${sql.raw(coltype)}
44
+ `.execute(db);
45
+ }
46
+ });
47
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@socialgouv/matomo-postgres",
3
3
  "description": "Extract visitor events from Matomo API and push to Postgres",
4
- "version": "2.4.3",
4
+ "version": "2.4.4",
5
5
  "packageManager": "pnpm@10.28.1",
6
6
  "types": "types/index.d.ts",
7
7
  "license": "Apache-2.0",