Skip to content

Commit 3b30bb1

Browse files
jmwskilaurenzlong
authored andcommitted
Add prettier formatting for fs-bq-schema-views script (#82)
1 parent 85fbef1 commit 3b30bb1

File tree

6 files changed

+293
-127
lines changed

6 files changed

+293
-127
lines changed

firestore-bigquery-export/scripts/gen-schema-view/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"build": "npm run clean && npm run compile",
1313
"clean": "rimraf ./lib",
1414
"compile": "tsc",
15+
"format": "prettier --write **/*.ts",
1516
"gen-schema-views": "node ./lib/index.js",
1617
"mocha": "nyc mocha -r ts-node/register --opts mocha.opts",
1718
"prepare": "npm run build",
@@ -47,6 +48,7 @@
4748
"nyc": "^14.0.0",
4849
"mocha": "^5.2.0",
4950
"mocha-typescript": "*",
51+
"prettier": "1.15.2",
5052
"typescript": "^3.5.2",
5153
"ts-node": "^7.0.1"
5254
}

firestore-bigquery-export/scripts/gen-schema-view/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ async function parseConfig(): Promise<CliConfig> {
154154
projectId: program.project,
155155
datasetId: program.dataset,
156156
tableNamePrefix: program.tableNamePrefix,
157-
schemas: readSchemas(program.schemaFiles)
157+
schemas: readSchemas(program.schemaFiles),
158158
};
159159
}
160160
const {
@@ -168,7 +168,7 @@ async function parseConfig(): Promise<CliConfig> {
168168
datasetId: dataset,
169169
tableNamePrefix: tableNamePrefix,
170170
schemas: readSchemas(
171-
schemaFiles.split(",").map((schemaFileName) => schemaFileName.trim()),
171+
schemaFiles.split(",").map((schemaFileName) => schemaFileName.trim())
172172
),
173173
};
174174
}

firestore-bigquery-export/scripts/gen-schema-view/src/logs.ts

+13-7
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,25 @@
1616

1717
import { FirestoreSchema } from "./schema";
1818

19-
export const bigQuerySchemaViewCreating = (name: string, schema: FirestoreSchema, query) => {
20-
console.log(`BigQuery creating schema view ${name}:\nSchema:\n` +
21-
`${JSON.stringify(schema)}\nQuery:\n${query}`);
22-
}
19+
export const bigQuerySchemaViewCreating = (
20+
name: string,
21+
schema: FirestoreSchema,
22+
query
23+
) => {
24+
console.log(
25+
`BigQuery creating schema view ${name}:\nSchema:\n` +
26+
`${JSON.stringify(schema)}\nQuery:\n${query}`
27+
);
28+
};
2329

2430
export const bigQuerySchemaViewCreated = (name: string) => {
2531
console.log(`BigQuery created schema view ${name}\n`);
26-
}
32+
};
2733

2834
export const bigQueryViewCreating = (view: string) => {
2935
console.log(`BigQuery created view ${view}`);
30-
}
36+
};
3137

3238
export const bigQueryViewCreated = (view: string) => {
3339
console.log(`BigQuery created view ${view}`);
34-
}
40+
};

firestore-bigquery-export/scripts/gen-schema-view/src/schema.ts

+159-64
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,13 @@ export class FirestoreBigQuerySchemaViewFactory {
7474
datasetId: string,
7575
tableNamePrefix: string,
7676
schemaName: string,
77-
firestoreSchema: FirestoreSchema,
77+
firestoreSchema: FirestoreSchema
7878
): Promise<bigquery.Table> {
7979
const rawChangeLogTableName = changeLog(raw(tableNamePrefix));
8080
const latestRawViewName = latest(raw(tableNamePrefix));
81-
const changeLogSchemaViewName = changeLog(schema(tableNamePrefix, schemaName));
81+
const changeLogSchemaViewName = changeLog(
82+
schema(tableNamePrefix, schemaName)
83+
);
8284
const latestSchemaViewName = latest(schema(tableNamePrefix, schemaName));
8385
const dataset = this.bq.dataset(datasetId);
8486

@@ -99,8 +101,16 @@ export class FirestoreBigQuerySchemaViewFactory {
99101
const [latestViewExists] = await latestView.exists();
100102

101103
if (!viewExists) {
102-
const schemaView = userSchemaView(datasetId, rawChangeLogTableName, firestoreSchema);
103-
logs.bigQuerySchemaViewCreating(changeLogSchemaViewName, firestoreSchema, schemaView.query);
104+
const schemaView = userSchemaView(
105+
datasetId,
106+
rawChangeLogTableName,
107+
firestoreSchema
108+
);
109+
logs.bigQuerySchemaViewCreating(
110+
changeLogSchemaViewName,
111+
firestoreSchema,
112+
schemaView.query
113+
);
104114
const options = {
105115
friendlyName: changeLogSchemaViewName,
106116
view: schemaView,
@@ -110,8 +120,16 @@ export class FirestoreBigQuerySchemaViewFactory {
110120
}
111121

112122
if (!latestViewExists) {
113-
const latestSchemaView = buildSchemaViewQuery(datasetId, latestRawViewName, firestoreSchema);
114-
logs.bigQuerySchemaViewCreating(latestSchemaViewName, firestoreSchema, latestSchemaView);
123+
const latestSchemaView = buildSchemaViewQuery(
124+
datasetId,
125+
latestRawViewName,
126+
firestoreSchema
127+
);
128+
logs.bigQuerySchemaViewCreating(
129+
latestSchemaViewName,
130+
firestoreSchema,
131+
latestSchemaView
132+
);
115133
const latestOptions = {
116134
fiendlyName: latestSchemaViewName,
117135
view: latestSchemaView,
@@ -122,7 +140,6 @@ export class FirestoreBigQuerySchemaViewFactory {
122140

123141
return view;
124142
}
125-
126143
}
127144

128145
/**
@@ -132,7 +149,7 @@ export class FirestoreBigQuerySchemaViewFactory {
132149
export const userSchemaView = (
133150
datasetId: string,
134151
tableName: string,
135-
schema: FirestoreSchema,
152+
schema: FirestoreSchema
136153
) => ({
137154
query: buildSchemaViewQuery(datasetId, tableName, schema),
138155
useLegacySql: false,
@@ -148,14 +165,18 @@ export const buildSchemaViewQuery = (
148165
rawTableName: string,
149166
schema: FirestoreSchema
150167
): string => {
151-
const [fieldExtractors, fieldArrays] = processFirestoreSchema(datasetId, "data", schema);
152-
const fieldValueSelectorClauses = Object.values(fieldExtractors).join(', ');
168+
const [fieldExtractors, fieldArrays] = processFirestoreSchema(
169+
datasetId,
170+
"data",
171+
schema
172+
);
173+
const fieldValueSelectorClauses = Object.values(fieldExtractors).join(", ");
153174
const schemaHasArrays = fieldArrays.length > 0;
154175
let query = `
155176
SELECT
156177
document_name,
157178
timestamp,
158-
operation${fieldValueSelectorClauses.length > 0 ? `,`: ``}
179+
operation${fieldValueSelectorClauses.length > 0 ? `,` : ``}
159180
${fieldValueSelectorClauses}
160181
FROM
161182
\`${process.env.PROJECT_ID}.${datasetId}.${rawTableName}\`
@@ -171,14 +192,18 @@ export const buildSchemaViewQuery = (
171192
* of additional rows added per document will be the product of the lengths
172193
* of all the arrays.
173194
*/
174-
query = `${subSelectQuery(query)} ${rawTableName} ${fieldArrays.map(arrayFieldName =>
175-
`CROSS JOIN UNNEST(${rawTableName}.${arrayFieldName})
195+
query = `${subSelectQuery(query)} ${rawTableName} ${fieldArrays
196+
.map(
197+
(arrayFieldName) =>
198+
`CROSS JOIN UNNEST(${rawTableName}.${arrayFieldName})
176199
AS ${arrayFieldName}_member
177-
WITH OFFSET ${arrayFieldName}_index`).join(' ')}`;
200+
WITH OFFSET ${arrayFieldName}_index`
201+
)
202+
.join(" ")}`;
178203
}
179204
query = sqlFormatter.format(query);
180205
return query;
181-
}
206+
};
182207

183208
/**
184209
* Given a Cloud Firestore schema which may contain values for any type present
@@ -200,10 +225,19 @@ export function processFirestoreSchema(
200225
if (!transformer) {
201226
transformer = (selector: string) => selector;
202227
}
203-
let extractors: { [fieldName: string]: string; } = {};
228+
let extractors: { [fieldName: string]: string } = {};
204229
let arrays: string[] = [];
205230
let geopoints: string[] = [];
206-
processFirestoreSchemaHelper(datasetId, dataFieldName, /*prefix=*/[], schema, arrays, geopoints, extractors, transformer);
231+
processFirestoreSchemaHelper(
232+
datasetId,
233+
dataFieldName,
234+
/*prefix=*/ [],
235+
schema,
236+
arrays,
237+
geopoints,
238+
extractors,
239+
transformer
240+
);
207241
return [extractors, arrays, geopoints];
208242
}
209243

@@ -246,7 +280,13 @@ function processFirestoreSchemaHelper(
246280
);
247281
return;
248282
}
249-
const fieldNameToSelector = (processLeafField(datasetId, "data", prefix, field, transformer));
283+
const fieldNameToSelector = processLeafField(
284+
datasetId,
285+
"data",
286+
prefix,
287+
field,
288+
transformer
289+
);
250290
for (let fieldName in fieldNameToSelector) {
251291
extractors[fieldName] = fieldNameToSelector[fieldName];
252292
}
@@ -278,46 +318,87 @@ const processLeafField = (
278318
let fieldNameToSelector = {};
279319
let selector;
280320
switch (field.type) {
281-
case "null":
282-
selector = transformer(`NULL`);
283-
break;
284-
case "string":
285-
case "reference":
286-
selector = jsonExtract(dataFieldName, extractPrefix, field, ``, transformer);
287-
break;
288-
case "array":
289-
selector = firestoreArray(datasetId, jsonExtract(dataFieldName, extractPrefix, field, ``, transformer));
290-
break;
291-
case "boolean":
292-
selector = firestoreBoolean(datasetId, jsonExtract(dataFieldName, extractPrefix, field, ``, transformer));
293-
break;
294-
case "number":
295-
selector = firestoreNumber(datasetId, jsonExtract(dataFieldName, extractPrefix, field, ``, transformer));
296-
break;
297-
case "timestamp":
298-
selector = firestoreTimestamp(datasetId, jsonExtract(dataFieldName, extractPrefix, field, ``, transformer));
299-
break;
300-
case "geopoint":
301-
const latitude = jsonExtract(dataFieldName, extractPrefix, field, `._latitude`, transformer);
302-
const longitude = jsonExtract(dataFieldName, extractPrefix, field, `._longitude`, transformer);
303-
/*
304-
* We return directly from this branch because it's the only one that
305-
* generates multiple selector clauses.
306-
*/
307-
fieldNameToSelector[qualifyFieldName(prefix, field.name)] =
308-
`${firestoreGeopoint(
309-
datasetId,
310-
jsonExtract(dataFieldName, extractPrefix, field, ``, transformer)
311-
)} AS ${prefix.concat(field.name).join("_")}`;
312-
fieldNameToSelector[qualifyFieldName(prefix, `${field.name}_latitude`)] =
313-
`SAFE_CAST(${latitude} AS NUMERIC) AS ${qualifyFieldName(prefix, `${field.name}_latitude`)}`;
314-
fieldNameToSelector[qualifyFieldName(prefix, `${field.name}_longitude`)] =
315-
`SAFE_CAST(${longitude} AS NUMERIC) AS ${qualifyFieldName(prefix, `${field.name}_longitude`)}`;
316-
return fieldNameToSelector;
321+
case "null":
322+
selector = transformer(`NULL`);
323+
break;
324+
case "string":
325+
case "reference":
326+
selector = jsonExtract(
327+
dataFieldName,
328+
extractPrefix,
329+
field,
330+
``,
331+
transformer
332+
);
333+
break;
334+
case "array":
335+
selector = firestoreArray(
336+
datasetId,
337+
jsonExtract(dataFieldName, extractPrefix, field, ``, transformer)
338+
);
339+
break;
340+
case "boolean":
341+
selector = firestoreBoolean(
342+
datasetId,
343+
jsonExtract(dataFieldName, extractPrefix, field, ``, transformer)
344+
);
345+
break;
346+
case "number":
347+
selector = firestoreNumber(
348+
datasetId,
349+
jsonExtract(dataFieldName, extractPrefix, field, ``, transformer)
350+
);
351+
break;
352+
case "timestamp":
353+
selector = firestoreTimestamp(
354+
datasetId,
355+
jsonExtract(dataFieldName, extractPrefix, field, ``, transformer)
356+
);
357+
break;
358+
case "geopoint":
359+
const latitude = jsonExtract(
360+
dataFieldName,
361+
extractPrefix,
362+
field,
363+
`._latitude`,
364+
transformer
365+
);
366+
const longitude = jsonExtract(
367+
dataFieldName,
368+
extractPrefix,
369+
field,
370+
`._longitude`,
371+
transformer
372+
);
373+
/*
374+
* We return directly from this branch because it's the only one that
375+
* generates multiple selector clauses.
376+
*/
377+
fieldNameToSelector[
378+
qualifyFieldName(prefix, field.name)
379+
] = `${firestoreGeopoint(
380+
datasetId,
381+
jsonExtract(dataFieldName, extractPrefix, field, ``, transformer)
382+
)} AS ${prefix.concat(field.name).join("_")}`;
383+
fieldNameToSelector[
384+
qualifyFieldName(prefix, `${field.name}_latitude`)
385+
] = `SAFE_CAST(${latitude} AS NUMERIC) AS ${qualifyFieldName(
386+
prefix,
387+
`${field.name}_latitude`
388+
)}`;
389+
fieldNameToSelector[
390+
qualifyFieldName(prefix, `${field.name}_longitude`)
391+
] = `SAFE_CAST(${longitude} AS NUMERIC) AS ${qualifyFieldName(
392+
prefix,
393+
`${field.name}_longitude`
394+
)}`;
395+
return fieldNameToSelector;
317396
}
318-
fieldNameToSelector[qualifyFieldName(prefix, field.name)] = `${selector} AS ${qualifyFieldName(prefix, field.name)}`;
397+
fieldNameToSelector[
398+
qualifyFieldName(prefix, field.name)
399+
] = `${selector} AS ${qualifyFieldName(prefix, field.name)}`;
319400
return fieldNameToSelector;
320-
}
401+
};
321402

322403
/**
323404
* Extract a field from a raw JSON string that lives in the column
@@ -343,8 +424,12 @@ const jsonExtract = (
343424
subselector: string = "",
344425
transformer: (selector: string) => string
345426
) => {
346-
return (transformer(`JSON_EXTRACT(${dataFieldName}, \'\$.${prefix.length > 0 ? `${prefix}.`: ``}${field.name}${subselector}\')`));
347-
}
427+
return transformer(
428+
`JSON_EXTRACT(${dataFieldName}, \'\$.${
429+
prefix.length > 0 ? `${prefix}.` : ``
430+
}${field.name}${subselector}\')`
431+
);
432+
};
348433

349434
/**
350435
* Given a select query, $QUERY, return a query that wraps the result in an
@@ -358,14 +443,24 @@ const jsonExtract = (
358443
* @param filter an array of field names to filter out from `query`
359444
*/
360445
export function subSelectQuery(query: string, filter?: string[]): string {
361-
return (`SELECT * ${(filter && filter.length > 0) ? `EXCEPT (${filter.join(', ')})` : ``} FROM (${query})`);
446+
return `SELECT * ${
447+
filter && filter.length > 0 ? `EXCEPT (${filter.join(", ")})` : ``
448+
} FROM (${query})`;
362449
}
363450

364451
function qualifyFieldName(prefix: string[], name: string): string {
365452
return prefix.concat(name).join("_");
366-
}
453+
}
367454

368-
export function latest(tableName: string): string { return `${tableName}_latest`; };
369-
export function schema(tableName: string, schemaName: string): string { return `${tableName}_schema_${schemaName}`; };
370-
export function raw(tableName: string): string { return `${tableName}_raw`; };
371-
export function changeLog(tableName: string): string { return `${tableName}_changelog`; };
455+
export function latest(tableName: string): string {
456+
return `${tableName}_latest`;
457+
}
458+
export function schema(tableName: string, schemaName: string): string {
459+
return `${tableName}_schema_${schemaName}`;
460+
}
461+
export function raw(tableName: string): string {
462+
return `${tableName}_raw`;
463+
}
464+
export function changeLog(tableName: string): string {
465+
return `${tableName}_changelog`;
466+
}

0 commit comments

Comments
 (0)