ffc-pay-etl-framework 1.0.0 → 1.1.0-alpha.10

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.
@@ -1,43 +1,52 @@
1
1
  const EventEmitter = require('node:events');
2
2
  const { Transform } = require('node:stream');
3
- const { Sequelize } = require('sequelize');
4
3
  const debug = require('debug')('destination');
5
4
  const DEFAULT_PORT = 5432;
6
5
  function isKeyWord(column) {
7
6
  return ['USER'].includes(column.toUpperCase());
8
7
  }
9
8
  function getMappingForColumn(mapping, column) {
9
+ if (mapping.length === 0) {
10
+ return;
11
+ }
10
12
  const [map] = mapping.filter(m => m.column === column);
11
13
  return map;
12
14
  }
15
+ function hasReturningColumns(mapping) {
16
+ return mapping.filter(m => m.returning === true).length > 0;
17
+ }
18
+ function getReturningColumns(mapping) {
19
+ return mapping.filter(m => m.returning === true).map(m => m === null || m === void 0 ? void 0 : m.targetColumn);
20
+ }
13
21
  function writeInsertStatement(columnMapping, table, chunk) {
14
22
  let statement = `INSERT INTO ${table} (${chunk._columns.map(column => {
15
23
  const mapping = getMappingForColumn(columnMapping, column);
16
- return mapping.targetColumn
24
+ return (mapping === null || mapping === void 0 ? void 0 : mapping.targetColumn)
17
25
  ?
18
26
  isKeyWord(mapping.targetColumn)
19
27
  ? `"${mapping.targetColumn}"`
20
28
  : mapping.targetColumn
21
29
  : isKeyWord(column)
22
- ? `"${mapping.column}"`
23
- : mapping.column;
30
+ ? `"${mapping === null || mapping === void 0 ? void 0 : mapping.column}"`
31
+ : mapping === null || mapping === void 0 ? void 0 : mapping.column;
24
32
  })
25
33
  .join(",")}) VALUES (${chunk._columns.map((column, index) => {
26
34
  const mapping = getMappingForColumn(columnMapping, column);
27
- if (!mapping)
28
- debug('Mapping not found for column %s', column);
29
- if (mapping.targetType === "number" && (isNaN(chunk[index]) || chunk[index] === '')) {
35
+ if ((mapping === null || mapping === void 0 ? void 0 : mapping.targetType) === "number" && (isNaN(chunk[index]) || chunk[index] === '')) {
30
36
  debug('Source data is not a number');
31
37
  return 0;
32
38
  }
33
- if (mapping.targetType === "varchar" || mapping.targetType === "char") {
39
+ if ((mapping === null || mapping === void 0 ? void 0 : mapping.targetType) === "varchar" || (mapping === null || mapping === void 0 ? void 0 : mapping.targetType) === "char") {
34
40
  return `'${chunk[index]}'`;
35
41
  }
36
- if (mapping.targetType === "date") {
37
- return `to_date('${chunk[index]}','${mapping.format}')`;
42
+ if ((mapping === null || mapping === void 0 ? void 0 : mapping.targetType) === "date") {
43
+ return `to_date('${chunk[index]}','${mapping === null || mapping === void 0 ? void 0 : mapping.format}')`;
38
44
  }
39
45
  return chunk[index] ? chunk[index] : 'null';
40
46
  })})`;
47
+ if (hasReturningColumns(columnMapping)) {
48
+ statement = statement + ` RETURNING ${getReturningColumns(columnMapping).join(',')}`;
49
+ }
41
50
  return statement;
42
51
  }
43
52
  /**
@@ -67,7 +76,7 @@ function PostgresDestination(options) {
67
76
  write(chunk, _, callback) {
68
77
  let insertStatement;
69
78
  // @ts-ignore
70
- if (chunk.errors.length === 0 | options.includeErrors) {
79
+ if (chunk.errors.length === 0 || options.includeErrors) {
71
80
  insertStatement = writeInsertStatement(mapping, table, chunk);
72
81
  debug('Insert statement: [%s]', insertStatement);
73
82
  // @ts-ignore
@@ -99,6 +108,7 @@ function PostgresDestination(options) {
99
108
  }
100
109
  });
101
110
  Object.assign(Transform.prototype, {
111
+ type: 'PostgresDestination',
102
112
  setConnection: function (connection) {
103
113
  this.connection = connection;
104
114
  }.bind(transform),
@@ -116,5 +126,7 @@ module.exports = {
116
126
  PostgresDestination,
117
127
  writeInsertStatement,
118
128
  isKeyWord,
119
- getMappingForColumn
129
+ getMappingForColumn,
130
+ hasReturningColumns,
131
+ getReturningColumns
120
132
  };
@@ -3,6 +3,7 @@ const EventEmitter = require('node:events');
3
3
  const util = require('node:util');
4
4
  const { RowMetaData } = require("./rowMetaData");
5
5
  const { compose } = require("node:stream");
6
+ const { Destinations } = require('..');
6
7
  /**
7
8
  * @typedef {Object} Etl
8
9
  * @function loader
@@ -18,7 +19,8 @@ const { compose } = require("node:stream");
18
19
  */
19
20
  function Etl() {
20
21
  EventEmitter.call(this);
21
- let self = this;
22
+ const self = this;
23
+ self.store = [];
22
24
  self.beforeETLList = [];
23
25
  self.connectionList = [];
24
26
  self.validatorList = [];
@@ -46,6 +48,7 @@ function Etl() {
46
48
  throw new Error(`Connection with name ${connectionname} not found`);
47
49
  }
48
50
  pipelineTask.setConnection(connection);
51
+ pipelineTask.setETL(self);
49
52
  self.beforeETLList.push(pipelineTask);
50
53
  return self;
51
54
  };
@@ -60,10 +63,18 @@ function Etl() {
60
63
  this.destination = (destination, ...tasks) => {
61
64
  const connectionname = destination.getConnectionName();
62
65
  const connection = this.connectionList.filter(c => c.name === connectionname)[0];
63
- if (connection) {
66
+ if (!connection && destination.type === 'PostgresDestination') {
67
+ throw new Error(`No connection could be found with name ${connectionname}`);
68
+ }
69
+ else {
64
70
  destination.setConnection(connection);
65
71
  }
66
- tasks && destination.setTasks(tasks);
72
+ if (tasks) {
73
+ for (const task of tasks) {
74
+ task.setETL(self);
75
+ }
76
+ destination.setTasks(tasks);
77
+ }
67
78
  self.destinationList.push(destination);
68
79
  return self;
69
80
  };
@@ -16,5 +16,7 @@ export function PostgresDestination(options: {
16
16
  export function writeInsertStatement(columnMapping: any, table: any, chunk: any): string;
17
17
  export function isKeyWord(column: any): boolean;
18
18
  export function getMappingForColumn(mapping: any, column: any): any;
19
+ export function hasReturningColumns(mapping: any): boolean;
20
+ export function getReturningColumns(mapping: any): any;
19
21
  import { Transform } from "stream";
20
22
  //# sourceMappingURL=postgresDestination.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"postgresDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/postgresDestination.js"],"names":[],"mappings":"AA6CA;;;;;;;;GAQG;AACH;IAN2B,KAAK;IACL,cAAc;IACd,OAAO;IACP,aAAa;cA+DvC;AAnGD,yFA4BC;AArCD,gDAEC;AAED,oEAGC"}
1
+ {"version":3,"file":"postgresDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/postgresDestination.js"],"names":[],"mappings":"AAuDA;;;;;;;;GAQG;AACH;IAN2B,KAAK;IACL,cAAc;IACd,OAAO;IACP,aAAa;cAgEvC;AAtGD,yFA8BC;AAhDD,gDAEC;AAED,oEAIC;AAED,2DAEC;AAED,uDAEC"}
@@ -14,6 +14,7 @@ export type Etl = any;
14
14
  */
15
15
  export function Etl(): void;
16
16
  export class Etl {
17
+ store: any[];
17
18
  beforeETLList: any[];
18
19
  connectionList: any[];
19
20
  validatorList: any[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/index.js"],"names":[],"mappings":";AAMA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,4BAwEC;;IArEG,qBAAuB;IACvB,sBAAwB;IACxB,qBAAuB;IACvB,0BAA4B;IAC5B,uBAAyB;IAEzB,6BAGC;IAED,gBAgBC;IAED,sCASC;IAED,qCAGC;IAED,mCAGC;IAED,wDAWC;IAED,mCAGC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/index.js"],"names":[],"mappings":";AAOA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,4BAgFC;;IA7EG,aAAe;IACf,qBAAuB;IACvB,sBAAwB;IACxB,qBAAuB;IACvB,0BAA4B;IAC5B,uBAAyB;IAEzB,6BAGC;IAED,gBAgBC;IAED,sCAUC;IAED,qCAGC;IAED,mCAGC;IAED,wDAiBC;IAED,mCAGC"}
@@ -2,44 +2,53 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const EventEmitter = require('node:events');
4
4
  const { Transform } = require('node:stream');
5
- const { Sequelize } = require('sequelize');
6
5
  const debug = require('debug')('destination');
7
6
  const DEFAULT_PORT = 5432;
8
7
  function isKeyWord(column) {
9
8
  return ['USER'].includes(column.toUpperCase());
10
9
  }
11
10
  function getMappingForColumn(mapping, column) {
11
+ if (mapping.length === 0) {
12
+ return;
13
+ }
12
14
  const [map] = mapping.filter(m => m.column === column);
13
15
  return map;
14
16
  }
17
+ function hasReturningColumns(mapping) {
18
+ return mapping.filter(m => m.returning === true).length > 0;
19
+ }
20
+ function getReturningColumns(mapping) {
21
+ return mapping.filter(m => m.returning === true).map(m => m?.targetColumn);
22
+ }
15
23
  function writeInsertStatement(columnMapping, table, chunk) {
16
24
  let statement = `INSERT INTO ${table} (${chunk._columns.map(column => {
17
25
  const mapping = getMappingForColumn(columnMapping, column);
18
- return mapping.targetColumn
26
+ return mapping?.targetColumn
19
27
  ?
20
28
  isKeyWord(mapping.targetColumn)
21
29
  ? `"${mapping.targetColumn}"`
22
30
  : mapping.targetColumn
23
31
  : isKeyWord(column)
24
- ? `"${mapping.column}"`
25
- : mapping.column;
32
+ ? `"${mapping?.column}"`
33
+ : mapping?.column;
26
34
  })
27
35
  .join(",")}) VALUES (${chunk._columns.map((column, index) => {
28
36
  const mapping = getMappingForColumn(columnMapping, column);
29
- if (!mapping)
30
- debug('Mapping not found for column %s', column);
31
- if (mapping.targetType === "number" && (isNaN(chunk[index]) || chunk[index] === '')) {
37
+ if (mapping?.targetType === "number" && (isNaN(chunk[index]) || chunk[index] === '')) {
32
38
  debug('Source data is not a number');
33
39
  return 0;
34
40
  }
35
- if (mapping.targetType === "varchar" || mapping.targetType === "char") {
41
+ if (mapping?.targetType === "varchar" || mapping?.targetType === "char") {
36
42
  return `'${chunk[index]}'`;
37
43
  }
38
- if (mapping.targetType === "date") {
39
- return `to_date('${chunk[index]}','${mapping.format}')`;
44
+ if (mapping?.targetType === "date") {
45
+ return `to_date('${chunk[index]}','${mapping?.format}')`;
40
46
  }
41
47
  return chunk[index] ? chunk[index] : 'null';
42
48
  })})`;
49
+ if (hasReturningColumns(columnMapping)) {
50
+ statement = statement + ` RETURNING ${getReturningColumns(columnMapping).join(',')}`;
51
+ }
43
52
  return statement;
44
53
  }
45
54
  /**
@@ -69,7 +78,7 @@ function PostgresDestination(options) {
69
78
  write(chunk, _, callback) {
70
79
  let insertStatement;
71
80
  // @ts-ignore
72
- if (chunk.errors.length === 0 | options.includeErrors) {
81
+ if (chunk.errors.length === 0 || options.includeErrors) {
73
82
  insertStatement = writeInsertStatement(mapping, table, chunk);
74
83
  debug('Insert statement: [%s]', insertStatement);
75
84
  // @ts-ignore
@@ -100,6 +109,7 @@ function PostgresDestination(options) {
100
109
  }
101
110
  });
102
111
  Object.assign(Transform.prototype, {
112
+ type: 'PostgresDestination',
103
113
  setConnection: function (connection) {
104
114
  this.connection = connection;
105
115
  }.bind(transform),
@@ -116,5 +126,7 @@ module.exports = {
116
126
  PostgresDestination,
117
127
  writeInsertStatement,
118
128
  isKeyWord,
119
- getMappingForColumn
129
+ getMappingForColumn,
130
+ hasReturningColumns,
131
+ getReturningColumns
120
132
  };
@@ -5,6 +5,7 @@ const EventEmitter = require('node:events');
5
5
  const util = require('node:util');
6
6
  const { RowMetaData } = require("./rowMetaData");
7
7
  const { compose } = require("node:stream");
8
+ const { Destinations } = require('..');
8
9
  /**
9
10
  * @typedef {Object} Etl
10
11
  * @function loader
@@ -20,7 +21,8 @@ const { compose } = require("node:stream");
20
21
  */
21
22
  function Etl() {
22
23
  EventEmitter.call(this);
23
- let self = this;
24
+ const self = this;
25
+ self.store = [];
24
26
  self.beforeETLList = [];
25
27
  self.connectionList = [];
26
28
  self.validatorList = [];
@@ -48,6 +50,7 @@ function Etl() {
48
50
  throw new Error(`Connection with name ${connectionname} not found`);
49
51
  }
50
52
  pipelineTask.setConnection(connection);
53
+ pipelineTask.setETL(self);
51
54
  self.beforeETLList.push(pipelineTask);
52
55
  return self;
53
56
  };
@@ -62,10 +65,18 @@ function Etl() {
62
65
  this.destination = (destination, ...tasks) => {
63
66
  const connectionname = destination.getConnectionName();
64
67
  const connection = this.connectionList.filter(c => c.name === connectionname)[0];
65
- if (connection) {
68
+ if (!connection && destination.type === 'PostgresDestination') {
69
+ throw new Error(`No connection could be found with name ${connectionname}`);
70
+ }
71
+ else {
66
72
  destination.setConnection(connection);
67
73
  }
68
- tasks && destination.setTasks(tasks);
74
+ if (tasks) {
75
+ for (const task of tasks) {
76
+ task.setETL(self);
77
+ }
78
+ destination.setTasks(tasks);
79
+ }
69
80
  self.destinationList.push(destination);
70
81
  return self;
71
82
  };
@@ -16,5 +16,7 @@ export function PostgresDestination(options: {
16
16
  export function writeInsertStatement(columnMapping: any, table: any, chunk: any): string;
17
17
  export function isKeyWord(column: any): boolean;
18
18
  export function getMappingForColumn(mapping: any, column: any): any;
19
+ export function hasReturningColumns(mapping: any): boolean;
20
+ export function getReturningColumns(mapping: any): any;
19
21
  import { Transform } from "stream";
20
22
  //# sourceMappingURL=postgresDestination.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"postgresDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/postgresDestination.js"],"names":[],"mappings":"AA6CA;;;;;;;;GAQG;AACH;IAN2B,KAAK;IACL,cAAc;IACd,OAAO;IACP,aAAa;cA+DvC;AAnGD,yFA4BC;AArCD,gDAEC;AAED,oEAGC"}
1
+ {"version":3,"file":"postgresDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/postgresDestination.js"],"names":[],"mappings":"AAuDA;;;;;;;;GAQG;AACH;IAN2B,KAAK;IACL,cAAc;IACd,OAAO;IACP,aAAa;cAgEvC;AAtGD,yFA8BC;AAhDD,gDAEC;AAED,oEAIC;AAED,2DAEC;AAED,uDAEC"}
@@ -14,6 +14,7 @@ export type Etl = any;
14
14
  */
15
15
  export function Etl(): void;
16
16
  export class Etl {
17
+ store: any[];
17
18
  beforeETLList: any[];
18
19
  connectionList: any[];
19
20
  validatorList: any[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/index.js"],"names":[],"mappings":";AAMA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,4BAwEC;;IArEG,qBAAuB;IACvB,sBAAwB;IACxB,qBAAuB;IACvB,0BAA4B;IAC5B,uBAAyB;IAEzB,6BAGC;IAED,gBAgBC;IAED,sCASC;IAED,qCAGC;IAED,mCAGC;IAED,wDAWC;IAED,mCAGC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/index.js"],"names":[],"mappings":";AAOA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,4BAgFC;;IA7EG,aAAe;IACf,qBAAuB;IACvB,sBAAwB;IACxB,qBAAuB;IACvB,0BAA4B;IAC5B,uBAAyB;IAEzB,6BAGC;IAED,gBAgBC;IAED,sCAUC;IAED,qCAGC;IAED,mCAGC;IAED,wDAiBC;IAED,mCAGC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ffc-pay-etl-framework",
3
- "version": "1.0.0",
3
+ "version": "1.1.0-alpha.10",
4
4
  "publisher": "Defra",
5
5
  "main": "dist/cjs/index.js",
6
6
  "private": false,
@@ -13,7 +13,7 @@
13
13
  "build:esm": "tsc -p ./tsconfig.esm.json && mv dist/esm/index.js dist/esm/index.mjs",
14
14
  "build:cjs": "tsc -p ./tsconfig.cjs.json",
15
15
  "prepack": "npm run build",
16
- "example": "node ./src/examples/csv-multi-tool-validator.js"
16
+ "example": "node ./src/examples/sql-return-values.js"
17
17
  },
18
18
  "keywords": [
19
19
  "ETL"