globalstorage
Version:
Global Storage is a Global Distributed Data Warehouse
267 lines (215 loc) • 8.84 kB
JavaScript
;
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var _require = require('metaschema'),
extractDecorator = _require.extractDecorator;
var transformations = require('./transformations');
var escapeString = function escapeString(value) {
var backslash = false;
var escaped = "'";
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = value[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var character = _step.value;
if (character === "'") {
escaped += "''";
} else if (character === '\\') {
escaped += '\\\\';
backslash = true;
} else {
escaped += character;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
escaped += "'";
return backslash ? " E".concat(escaped) : escaped;
};
var escapeIdentifier = function escapeIdentifier(name) {
return "\"".concat(name, "\"");
};
var escapeKey = function escapeKey(key) {
return key.split('.').map(function (k) {
return k === '*' ? '*' : escapeIdentifier(k);
}).join('.');
};
var escapeValue = function escapeValue(value) {
var type = _typeof(value);
if (type === 'number') return value;
if (type === 'string') return escapeString(value);
if (value instanceof Date) return "'".concat(value.toISOString(), "'");
throw new TypeError('Unsupported value (${value}) type');
};
var PREDEFINED_DOMAINS = {
Time: 'time with time zone',
DateDay: 'date',
DateTime: 'timestamp with time zone',
JSON: 'jsonb',
Money: 'money'
};
var IGNORED_DOMAINS = ['List', 'Enum', 'HashMap', 'HashSet']; // https://tools.ietf.org/html/rfc3629#section-3
var utf8bytesLastCodePoints = {
1: 0x007f,
2: 0x07ff,
3: 0xffff
};
var utf8codePointSize = function utf8codePointSize(codePoint) {
for (var byteCount = 1; byteCount <= 3; byteCount++) {
if (codePoint <= utf8bytesLastCodePoints[byteCount]) {
return byteCount;
}
}
return 4;
};
var asciiCP = {
aToZLower: ['a'.codePointAt(0), 'z'.codePointAt(0)],
aToZUpper: ['A'.codePointAt(0), 'Z'.codePointAt(0)],
underscore: '_'.codePointAt(0),
numbers: ['0'.codePointAt(0), '9'.codePointAt(0)],
dollar: '$'.codePointAt(0)
};
var classMapping = {
Uint8Array: 'bytea',
Date: 'timestamp with time zone',
Uint64: 'bigint'
}; // https://github.com/postgres/postgres/blob/5f6b0e6d69f1087847c8456b3f69761c950d52c6/src/backend/utils/adt/misc.c#L723
var isValidIdentifierStart = function isValidIdentifierStart(cp) {
return cp === asciiCP.underscore || cp >= asciiCP.aToZLower[0] && cp <= asciiCP.aToZLower[1] || cp >= asciiCP.aToZUpper[0] && cp <= asciiCP.aToZUpper[1] || cp >= 0x80;
}; // https://github.com/postgres/postgres/blob/5f6b0e6d69f1087847c8456b3f69761c950d52c6/src/backend/utils/adt/misc.c#L741
var isValidIdentifierCont = function isValidIdentifierCont(cp) {
return cp >= asciiCP.numbers[0] && cp <= asciiCP.numbers[1] || cp === asciiCP.dollar || isValidIdentifierStart(cp);
};
var singleUnitUtf16 = (1 << 16) - 1; // https://www.postgresql.org/docs/10/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
var isValidIdentifier = function isValidIdentifier(name) {
var length = 0;
for (var i = 0; i < name.length; i++) {
var codePoint = name.codePointAt(i);
if (i === 0) {
if (!isValidIdentifierStart(codePoint)) {
return false;
}
} else if (!isValidIdentifierCont(codePoint)) {
return false;
}
length += utf8codePointSize(codePoint);
if (codePoint > singleUnitUtf16) i++;
}
return length < 64;
};
var validateIdentifier = function validateIdentifier(name, type) {
var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
if (!isValidIdentifier(name)) {
throw new Error("Cannot create ".concat(type, " ").concat(prefix).concat(name, " ") + 'because it is not a valid identifier');
}
};
var generateQueryParams = function generateQueryParams(count) {
var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
var params = '';
for (var i = start; i < start + count; i++) {
if (i !== start) {
params += ', ';
}
params += "$".concat(i);
}
return params;
};
var generateLinkQueryParams = function generateLinkQueryParams(count) {
var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
var params = '';
for (var i = start + 1; i < start + 1 + count; i++) {
if (i !== start + 1) {
params += ', ';
}
params += "($".concat(start, ", $").concat(i, ")");
}
return params;
};
var buildWhere = function buildWhere(query) {
var constraints = transformations.constraints(query);
var constraintsKeys = Object.keys(constraints);
if (constraintsKeys.length === 0) {
return ['', []];
}
var params = new Array(constraintsKeys.length);
return [' WHERE ' + constraintsKeys.map(function (key, i) {
var _constraints$key = _slicedToArray(constraints[key], 2),
cond = _constraints$key[0],
value = _constraints$key[1];
params[i] = value;
return "".concat(escapeKey(key), " ").concat(cond === '!' ? '!=' : cond, " $").concat(i + 1);
}).join(' AND '), params];
};
var generateDeleteQuery = function generateDeleteQuery(category, includedCategories, query) {
var escapedCategory = escapeIdentifier(category);
var deleteQuery = "WITH ToDelete AS (SELECT ".concat(escapedCategory, ".\"Id\"") + " FROM ".concat(escapedCategory);
includedCategories.forEach(function (category) {
var includedCategory = escapeIdentifier(category);
deleteQuery += " INNER JOIN ".concat(includedCategory, " ON") + " ".concat(escapedCategory, ".\"Id\" = ").concat(includedCategory, ".\"Id\"");
});
var _buildWhere = buildWhere(query),
_buildWhere2 = _slicedToArray(_buildWhere, 2),
where = _buildWhere2[0],
whereParams = _buildWhere2[1];
deleteQuery += where + ')';
includedCategories.forEach(function (category) {
var includedCategory = escapeIdentifier(category);
deleteQuery += ", ".concat(category, " AS (DELETE FROM ").concat(includedCategory) + ' WHERE "Id" IN (SELECT "Id" FROM ToDelete))';
});
deleteQuery += " DELETE FROM ".concat(escapedCategory) + ' WHERE "Id" IN (SELECT "Id" FROM ToDelete)';
return [deleteQuery, whereParams];
};
var fitInSchema = function fitInSchema(object, schema) {
var result = {};
if (object.Id) {
result.Id = object.Id;
}
for (var prop in schema) {
var field = schema[prop];
var value = object[prop];
if (value !== undefined) {
result[prop] = value;
} else if (extractDecorator(field) === 'Include') {
result[prop] = fitInSchema(object, field.definition);
}
}
return result;
};
var recreateIdTrigger = Symbol('recreateIdTrigger');
var uploadMetadata = Symbol('uploadMetadata');
module.exports = {
escapeString: escapeString,
escapeValue: escapeValue,
escapeIdentifier: escapeIdentifier,
escapeKey: escapeKey,
PREDEFINED_DOMAINS: PREDEFINED_DOMAINS,
IGNORED_DOMAINS: IGNORED_DOMAINS,
isValidIdentifier: isValidIdentifier,
validateIdentifier: validateIdentifier,
generateQueryParams: generateQueryParams,
generateLinkQueryParams: generateLinkQueryParams,
buildWhere: buildWhere,
generateDeleteQuery: generateDeleteQuery,
classMapping: classMapping,
fitInSchema: fitInSchema,
symbols: {
recreateIdTrigger: recreateIdTrigger,
uploadMetadata: uploadMetadata
}
};