UNPKG

@vulcan-sql/build

Version:

VulcanSQL package for building projects

142 lines 7.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CheckCache = void 0; const tslib_1 = require("tslib"); const core_1 = require("@vulcan-sql/core"); const middleware_1 = require("./middleware"); const constants_1 = require("./constants"); const ms_1 = require("ms"); class CheckCache extends middleware_1.SchemaParserMiddleware { handle(schemas, next) { var _a; return tslib_1.__awaiter(this, void 0, void 0, function* () { // check .yaml file has cache configuration const caches = schemas === null || schemas === void 0 ? void 0 : schemas.cache; const metadata = schemas.metadata; const isUsedCache = (_a = metadata === null || metadata === void 0 ? void 0 : metadata[constants_1.CACHE_METADATA_NAME]) === null || _a === void 0 ? void 0 : _a['isUsedTag']; if (!isUsedCache && !caches) return next(); // throw if cache not used in .sql file if (isUsedCache && !caches) { throw new core_1.ConfigurationError(`{% cache %} tag was used in SQL file, but the cache configurations was not found in schema "${schemas.urlPath}".`); } if (!isUsedCache && caches) { throw new core_1.ConfigurationError(`Can not configure the cache setting in schema "${schemas.urlPath}", {% cache %} tag not been used in SQL file.`); } this.checkCacheTableName(schemas); this.checkSQLHasValue(schemas); this.assignCacheProfile(schemas); this.checkRefreshSettings(schemas); this.checkIndexesHasValue(schemas); yield next(); }); } checkRefreshSettings(schemas) { const { cache: caches, urlPath } = schemas; for (const cache of caches) { const { refreshTime, refreshExpression, cacheTableName } = cache; if (!refreshTime && !refreshExpression) continue; if (refreshTime && refreshExpression) { throw new core_1.ConfigurationError(`Can not set "refreshTime" and "refreshExpression" at the same time in cache "${cacheTableName}" of schema "${urlPath}"`); } const options = refreshTime ? { type: 'refreshTime', timeInterval: refreshTime.every } : { type: 'refreshExpression', timeInterval: refreshExpression.every }; const message = this.checkRefreshInterval(options.timeInterval); if (message) throw new core_1.ConfigurationError(`The "${options.type}.every" of cache "${cacheTableName}" in schema "${urlPath}" is invalid: ${message}`); } } checkRefreshInterval(timeInterval) { if (!timeInterval) return 'Should have a value.'; const interval = (0, ms_1.default)(timeInterval); if (isNaN(interval)) return 'Invalid time string to convert.'; if (interval < 0) return 'Time can not be negative.'; return ''; } checkCacheTableName(schemas) { const caches = schemas === null || schemas === void 0 ? void 0 : schemas.cache; const cacheTableNames = []; caches === null || caches === void 0 ? void 0 : caches.forEach((cache) => { const { cacheTableName } = cache; // should have table name if (!cacheTableName) { throw new core_1.ConfigurationError(`The "cacheTableName" of cache in schema "${schemas.urlPath}" is not defined.`); } // table name should be unique if (cacheTableNames.includes(cacheTableName)) { throw new core_1.ConfigurationError(`The cacheTableName "${cacheTableName}" of cache in schema "${schemas.urlPath}" is not unique.`); } // table naming pattern // 1. start with a letter or underscore, and can only contain letters, numbers, and underscores // 2. the sub-characters contain letters, numbers, underscore, and dollar sign const pattern = /^[a-zA-Z_][a-zA-Z0-9_$]+$/; if (!pattern.test(cacheTableName)) { throw new core_1.ConfigurationError(`The cacheTableName "${cacheTableName}" in schema "${schemas.urlPath}" should meet the pattern "${pattern}".`); } cacheTableNames.push(cacheTableName); }); } // check sql is not empty checkSQLHasValue(schemas) { const { cache: caches, urlPath } = schemas; caches === null || caches === void 0 ? void 0 : caches.forEach((cache) => { const { sql, cacheTableName } = cache; if (!sql) { throw new core_1.ConfigurationError(`The "sql" of cache "${cacheTableName}" in schema "${urlPath}" is not defined or is empty.`); } }); } // check indexes value is not empty checkIndexesHasValue(schemas) { const { cache: caches, urlPath } = schemas; const indexNames = []; caches === null || caches === void 0 ? void 0 : caches.forEach(({ indexes, cacheTableName }) => { if (indexes) { Object.entries(indexes).forEach(([indexName, columnName]) => { if (!columnName || typeof columnName !== 'string') { throw new core_1.ConfigurationError(`The index "${indexName}" of cache "${cacheTableName}" in schema "${urlPath}" should be a string.`); } // index name should be unique even in different cache table name (duckdb could not create same index name on different table) if (indexNames.includes(indexName)) { throw new core_1.ConfigurationError(`The indexName "${indexName}" of cache in schema "${schemas.urlPath}" is not unique.`); } // index naming pattern // 1. start with a letter or underscore, and can only contain letters, numbers, and underscores // 2. the sub-characters contain letters, numbers, underscore, and dollar sign const pattern = /^[a-zA-Z_][a-zA-Z0-9_$]+$/; if (!pattern.test(indexName)) { throw new core_1.ConfigurationError(`The index name "${indexName}" in schema "${schemas.urlPath}" should meet the pattern "${pattern}".`); } indexNames.push(indexName); }); } }); } // assign the first profile in the schemas.profiles to the cache.profile if cache.profile is not defined // cache profile should exist in schemas.profiles assignCacheProfile(schemas) { const { cache: caches, profiles, urlPath } = schemas; if (!profiles) { throw new core_1.ConfigurationError(`The "profiles" of schema "${schemas.urlPath}" is not defined.`); } const defaultProfile = profiles[0]; for (const cache of caches) { const { profile, cacheTableName } = cache; if (!profile) { cache.profile = defaultProfile; continue; } // if cache.profile is not in profiles, throw error if (!profiles.includes(profile)) { throw new core_1.ConfigurationError(`The profile "${profile}" of cache "${cacheTableName}" in schema "${urlPath}" is not defined in the schema profiles.`); } } } } exports.CheckCache = CheckCache; //# sourceMappingURL=checkCache.js.map