@pittica/google-business-intelligence-helpers 1.15.1 → 1.15.3

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.
@@ -13,11 +13,13 @@
13
13
  // limitations under the License.
14
14
 
15
15
  const {
16
- getBucket
16
+ getBucket,
17
+ groupJson
17
18
  } = require("@pittica/google-cloud-storage-helpers");
18
19
  const {
19
20
  getDataset,
20
- jobDone
21
+ jobDone,
22
+ getTable
21
23
  } = require("@pittica/google-bigquery-helpers");
22
24
  const log = require("@pittica/logger-helpers");
23
25
  const {
@@ -33,13 +35,13 @@ const {
33
35
  * @param {string} dateFormat Date format string.
34
36
  * @returns {boolean} A value indicating whehter the job has been done.
35
37
  */
36
- exports.backup = async (id, bucket, projectId, dateFormat = "YYYY-MM-DD") => {
38
+ exports.backup = async (id, bucket, projectId = null, dateFormat = "YYYY-MM-DD") => {
37
39
  const dataset = await getDataset(id, {
38
40
  projectId
39
41
  });
40
42
  const [tables] = await dataset.getTables();
41
43
  const date = format(new Date(), dateFormat);
42
- return await exports.extract(bucket, date, tables, 0);
44
+ return await exports.extract(bucket, date, tables, 0, dataset.metadata.location, projectId);
43
45
  };
44
46
 
45
47
  /**
@@ -49,20 +51,22 @@ exports.backup = async (id, bucket, projectId, dateFormat = "YYYY-MM-DD") => {
49
51
  * @param {string} date Date in format YYYY-MM-DD.
50
52
  * @param {Array} tables An array of BigQuery tables.
51
53
  * @param {number} index Array index.
54
+ * @param {string} location Location of the BigQuery dataset.
55
+ * @param {string} projectId Google Cloud project ID.
52
56
  * @returns {boolean} A value indicating whehter the job has been done.
53
57
  */
54
- exports.extract = async (bucket, date, tables, index) => {
58
+ exports.extract = async (bucket, date, tables, index = 0, location = "us-central1", projectId = null) => {
55
59
  if (index < tables.length) {
56
60
  const table = tables[index];
57
- return await table.extract(getBucket(bucket).file(`${date}/${table.id}-*.json`), {
58
- location: "us-central1",
61
+ return await table.extract(getBucket(bucket, projectId).file(`${date}/${table.id}-*.json`), {
62
+ location,
59
63
  format: "json",
60
64
  gzip: false
61
65
  }).then(async response => {
62
66
  if (jobDone(response)) {
63
67
  const [job] = response;
64
68
  log.success(`Job backup "${job.id}" for table "${table.id}" done.`);
65
- return await exports.extract(date, tables, index + 1);
69
+ return await exports.extract(bucket, date, tables, index + 1, location, projectId);
66
70
  } else {
67
71
  return false;
68
72
  }
@@ -88,7 +92,7 @@ exports.rollback = async (date, id, projectId, sourceBucket, destinationDataset)
88
92
  const dataset = await getDataset(id, {
89
93
  projectId
90
94
  });
91
- const bucket = getBucket(sourceBucket);
95
+ const bucket = getBucket(sourceBucket, projectId);
92
96
  const [response] = await bucket.getFiles({
93
97
  prefix: `${date}/`
94
98
  });
@@ -96,16 +100,19 @@ exports.rollback = async (date, id, projectId, sourceBucket, destinationDataset)
96
100
  log.info(`Begin rollback "${date}".`);
97
101
  Object.keys(files).forEach(async key => {
98
102
  const [table] = await dataset.table(key).get();
99
- files[key].forEach(filename => bigquery.dataset(destinationDataset, {
100
- location: dataset.metadata.location,
101
- projectId
102
- }).table(key).load(bucket.file(`${date}/${filename}`), {
103
- sourceFormat: "NEWLINE_DELIMITED_JSON",
104
- schema: table.metadata.schema,
105
- timePartitioning: table.metadata.timePartitioning,
106
- location: table.metadata.location,
107
- tableConstraints: table.metadata.tableConstraints,
108
- partitionDefinition: table.metadata.partitionDefinition
109
- }));
103
+ files[key].forEach(async filename => {
104
+ const destination = await getTable(destinationDataset, key, {
105
+ projectId,
106
+ location: dataset.metadata.location
107
+ });
108
+ await destination.load(bucket.file(`${date}/${filename}`), {
109
+ sourceFormat: "NEWLINE_DELIMITED_JSON",
110
+ schema: table.metadata.schema,
111
+ timePartitioning: table.metadata.timePartitioning,
112
+ location: table.metadata.location,
113
+ tableConstraints: table.metadata.tableConstraints,
114
+ partitionDefinition: table.metadata.partitionDefinition
115
+ });
116
+ });
110
117
  });
111
118
  };
@@ -120,12 +120,13 @@ exports.getSafeFilenameFromBucket = ({
120
120
  * @param {string} output Path to save files.
121
121
  * @param {string} bucket Bucket name.
122
122
  * @param {string} dateFormat Date format string.
123
+ * @param {string} projectId Optional project ID.
123
124
  */
124
- exports.implode = async (date, output, bucket, dateFormat = "YYYY-MM-DD") => {
125
+ exports.implode = async (date, output, bucket, dateFormat = "YYYY-MM-DD", projectId = null) => {
125
126
  const folder = format(parse(date, dateFormat), dateFormat);
126
127
  const destination = path.join(output, ".tmp");
127
128
  const temporary = path.join(destination, folder);
128
- await downloadFolder(folder, bucket, destination).then(() => log.info(`Downloaded "gs://${bucket}/${folder}" to "${destination}".`)).catch(log.error);
129
+ await downloadFolder(folder, bucket, destination, projectId).then(() => log.info(`Downloaded "gs://${bucket}/${folder}" to "${destination}".`)).catch(log.error);
129
130
  const files = groupJson(fs.readdirSync(temporary));
130
131
  Object.keys(files).forEach(table => {
131
132
  const json = [];
@@ -155,10 +156,11 @@ exports.implode = async (date, output, bucket, dateFormat = "YYYY-MM-DD") => {
155
156
  *
156
157
  * @param {string} bucket Bucket name.
157
158
  * @param {number} days Number of days to keep.
159
+ * @param {string} projectId Optional project ID.
158
160
  * @returns {boolean} A value indicating whehter the job has been done.
159
161
  */
160
- exports.erase = async (bucket, days = process.env.BACKUP_KEEP_DAYS || 3) => {
161
- const b = getBucket(bucket);
162
+ exports.erase = async (bucket, days = process.env.BACKUP_KEEP_DAYS || 3, projectId = null) => {
163
+ const b = getBucket(bucket, projectId);
162
164
  const [files] = await b.getFiles();
163
165
  const result = {};
164
166
  files.forEach(({
@@ -169,9 +171,9 @@ exports.erase = async (bucket, days = process.env.BACKUP_KEEP_DAYS || 3) => {
169
171
  });
170
172
  const folders = Object.keys(result).sort();
171
173
  const blacklist = folders.slice(0, folders.length - parseInt(days));
172
- blacklist.forEach(async prefix => await b.deleteFiles({
174
+ await Promise.all(blacklist.map(async prefix => await b.deleteFiles({
173
175
  prefix
174
- }));
176
+ })));
175
177
  log.success("Backup bucket erased.");
176
178
  return true;
177
179
  };
@@ -41,7 +41,7 @@ exports.scriptBackup = backup;
41
41
  * @param {string} dateFormat Date format string.
42
42
  * @returns {boolean} A value indicating whehter the job has been done.
43
43
  */
44
- exports.scriptBackupErase = async (id, bucket, projectId, days, dateFormat = "YYYY-MM-DD") => await backup(id, bucket, projectId, dateFormat).then(async () => await erase(bucket, days));
44
+ exports.scriptBackupErase = async (id, bucket, projectId, days, dateFormat = "YYYY-MM-DD") => await backup(id, bucket, projectId, dateFormat).then(async () => await erase(bucket, days, projectId));
45
45
 
46
46
  /**
47
47
  * Rollback data using backup.
@@ -28,14 +28,15 @@ const {
28
28
  *
29
29
  * @param {string} bucket Bucket name.
30
30
  * @param {string} date Date to compare against.
31
+ * @param {string} projectId Google Cloud project ID.
31
32
  * @returns {Array} Array of files that are in the file but not in the bucket.
32
33
  */
33
- exports.scriptComparison = async (bucket, date = null) => {
34
+ exports.scriptComparison = async (bucket, date = null, projectId = null) => {
34
35
  if (bucket) {
35
36
  const day = date ? stringToDateUTC(date) : new Date();
36
37
  const filename = mergeFilename(day, "filelist", "txt");
37
- const content = await txtContentToArray(filename, bucket);
38
- const files = await listFiles(bucket);
38
+ const content = await txtContentToArray(filename, bucket, projectId);
39
+ const files = await listFiles(bucket, null, projectId);
39
40
  return content.filter(file => !files.includes(file));
40
41
  }
41
42
  };
@@ -24,13 +24,16 @@ const {
24
24
  * @param {string} output Path to save files.
25
25
  * @param {string} bucket Bucket name.
26
26
  * @param {string} dateFormat Date format string.
27
+ * @param {string} projectId Optional project ID.
27
28
  */
28
29
  exports.scriptImplode = implode;
30
+
29
31
  /**
30
32
  * Erases the bucket.
31
33
  *
32
34
  * @param {string} bucket Bucket name.
33
35
  * @param {number} days Number of days to keep.
36
+ * @param {string} projectId Optional project ID.
34
37
  * @returns {boolean} A value indicating whehter the job has been done.
35
38
  */
36
39
  exports.scriptErase = erase;
@@ -29,19 +29,19 @@ const {
29
29
  *
30
30
  * @param {string} bucket Bucket name.
31
31
  * @param {string} folder Path of the local folder to scan for schemas.
32
- * @returns {void}
32
+ * @param {string} projectId Optional project ID.
33
33
  */
34
- exports.scriptUnlistened = async (bucket, folder) => {
34
+ exports.scriptUnlistened = async (bucket, folder, projectId = null) => {
35
35
  if (bucket) {
36
- const storage = getStorage();
36
+ const storage = getStorage(projectId);
37
37
  const [files] = await getFiles(storage, bucket);
38
38
  if (files) {
39
- files.forEach(file => {
39
+ files.forEach(async file => {
40
40
  const {
41
41
  name
42
42
  } = splitName(file.id);
43
43
  if (!hasSchema(name, folder)) {
44
- deleteFile(file);
44
+ await deleteFile(file);
45
45
  }
46
46
  });
47
47
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pittica/google-business-intelligence-helpers",
3
3
  "private": false,
4
- "version": "1.15.1",
4
+ "version": "1.15.3",
5
5
  "description": "Helpers for business intelligence for Google Cloud.",
6
6
  "main": "dist/index.js",
7
7
  "scripts": {
@@ -36,8 +36,8 @@
36
36
  "node": ">=24.11.0"
37
37
  },
38
38
  "dependencies": {
39
- "@pittica/google-bigquery-helpers": "^1.6.1",
40
- "@pittica/google-cloud-storage-helpers": "^1.5.0",
39
+ "@pittica/google-bigquery-helpers": "^1.7.0",
40
+ "@pittica/google-cloud-storage-helpers": "^1.6.0",
41
41
  "@pittica/logger-helpers": "^1.2.2",
42
42
  "date-and-time": "^4.7.0"
43
43
  },