-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmakeRedshiftSql.js
151 lines (135 loc) · 4.19 KB
/
makeRedshiftSql.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import { fieldComparator, nameConverter } from './common.js';
const UUID_FIELDS_TYPE = "VARCHAR(254)";
const uuidFields = new Set([
"callId",
"clientId",
"peerConnectionId",
"trackId",
"streamId",
"sinkId",
"sfuStreamId",
"sfuSinkId",
"sfuId",
"transportId",
"padId",
"channelId",
]);
class RedshiftSql {
constructor({ name, desc}) {
this._name = nameConverter(name);
this._description = desc;
this._fields = [];
}
get name() {
return this._name;
}
addField({ name, type, desc, required }) {
this._fields.push({ name, type, desc, required });
}
make() {
this._fields.sort(fieldComparator);
return {
createTable: this._makeCreateTableString(),
csvColumnList: this._makeColumnCsvList(),
}
}
_makeCreateTableString() {
const tableName = this._name;
const result = [
`create table IF NOT EXISTS ${tableName} (`
]
const sortIds = new Set(Array.from(uuidFields).map(s => s.toLowerCase()));
const sortKeys = [];
const fields = new Set();
const fieldsLength = this._fields.length;
for (let i = 0; i < fieldsLength; ++i) {
const { type, required } = this._fields[i];
const name = this._fields[i].name.toLowerCase();
const properties = [
name,
type,
];
if (required) {
properties.push("not null");
}
if (sortIds.has(name)) {
sortKeys.push(name);
}
const column = properties.join(`\t`);
result.push(`\t${column}${i != fieldsLength - 1 ? ",":""}`);
// result.push(`\t${column},`);
fields.add(name);
}
result.push(`) diststyle even;`);
if (fields.has('serviceid')) {
result.push(`ALTER TABLE ${tableName} ALTER diststyle KEY DISTKEY serviceid;`);
}
if (0 < sortKeys.length) {
result.push(`ALTER TABLE ${tableName} ALTER COMPOUND SORTKEY (${sortKeys.join(", ")});`)
}
return result.join(`\n`);
}
_makeColumnCsvList() {
if (this._fields.length < 1) return "";
// return `"` + this._fields.map(field => field.name.toLowerCase()).join(`",\n"`) + `"`;
// return this._fields.map(field => field.name.toLowerCase()).join(`, `);
// console.log(this._fields);
return this._fields.map(field => field.name).join(`, `);
}
}
function getRedshiftType(fieldName, avroFieldType) {
if (avroFieldType === "string") {
if (uuidFields.has(fieldName)) {
return UUID_FIELDS_TYPE;
}
if (fieldName.endsWith("Id")) {
return "VARCHAR(1024)";
}
const lowerCase = fieldName.toLowerCase();
if (lowerCase.endsWith("state") || lowerCase.endsWith("protocol")) {
return "VARCHAR(1024)";
}
return "VARCHAR(65535)";
}
switch (avroFieldType) {
case "float":
return "REAL";
case "double":
return "REAL";
case "long":
return "BIGINT";
case "boolean":
return "BOOLEAN";
case "int":
return "INTEGER";
case "bytes":
return "VARCHAR(4096)";
default:
throw new Error(`Unsoppurted type ${avroFieldType} to convert it to redshift sql type`)
}
}
export function makeRedshiftSql(avroSchema) {
const result = new RedshiftSql({
name: avroSchema.name,
desc: avroSchema.doc,
});
for (const field of avroSchema.fields) {
const required = field.default === undefined;
const name = field.name;
const avroFieldType = required ? field.type : field.type[1];
const type = getRedshiftType(name, avroFieldType);
result.addField({
// name: name.toLowerCase(),
name: name,
doc: field.doc,
required,
type,
});
}
const { createTable, csvColumnList, knexSchema } = result.make();
return {
createTable,
csvColumnList,
knexSchema
}
}