UNPKG

@opengis/fastify-table

Version:

core-plugins

103 lines (80 loc) 4.28 kB
import config from '../../../../config.js'; import pgClient from '../pgClients.js'; // subfunc const getTable = ({ table }) => table.toLowerCase().replace(/[\n\r]+/g, ' ').split(' from ') .filter((el) => /^[a-z0-9_]+\.[a-z0-9_]+/.test(el)) .map((el) => el.split(/[ )]/)[0]); const loadedIndex = {}; // main func async function autoIndex({ table, columns: filter1, pg = pgClient.client, gin, }) { const filter = filter1.filter(el => el); if (!filter?.length || !table || process.env.NODE_ENV === 'unit test') return null; const attrs = filter.map((el) => (el.name || el).replace(/'/g, '')).filter(el => el?.indexOf('(') === -1).sort(); const types = filter.filter(el => (el?.name || el)?.indexOf?.('(') === -1).map((el) => (el.name ? el : { name: el })) .reduce((p, el) => ({ ...p, [el.name]: el.type || '-' }), {}); const redisKey = `autoindex1:${table}:${attrs.join(';')}`; const tableList = getTable({ table }); const existsCache = loadedIndex[redisKey]; if (existsCache && !config.disableCache) { return 'ok'; } const tbs = tableList[0]; const [ns, tbl] = tableList[0].split('.'); const { rows: index } = await pg.query(`select * from pg_indexes where tablename = '${tbl}' and schemaname = '${ns}'`); if (existsCache && !config.disableCache && index?.length > 0) { return null; } // console.log('autoindex', table, filter?.map((el) => el.name || el)); const { rows: cols } = await pg.query(`SELECT attrelid::regclass AS tbl, attname AS aname, atttypid::regtype AS datatype, atttypid FROM pg_attribute WHERE attrelid = '${tbs}'::regclass and attname = any('{ ${attrs} }')`); const qIndex = []; const indexAr = {}; // console.log(cols); for (let i = 0; i < cols.length; i += 1) { const el = cols[i]; el.relname = tbl; el.nspname = ns; const isGin = types[el.aname] === 'Text' || gin; const indexUsing = (el.datatype === 'geometry' ? 'gist' : null) || (isGin ? 'gin' : null) || 'btree'; const name = `${el.nspname}_${el.relname}_${el.aname}_${indexUsing}_idx`; const exists = index.filter((ind) => ind.tablename === el.relname && ind.schemaname === el.nspname && ind.indexdef.includes( isGin ? `gin (${el.aname} gin_trgm_ops)` : `btree (${el.aname})`, )); indexAr[el.aname] = { name, type: el.datatype, exists, // exists1, }; // drop /* if (exists?.length > 1) { exists.filter((ind, i1) => i1).forEach((ind) => qIndex.push(`DROP INDEX if exists ${ind.schemaname}.${ind.indexname} `)); } */ // add if (exists?.length <= (isGin ? 2 : 1)) { // console.log(`${name} - ${el.datatype}`); const suffix = isGin ? 'gin_trgm_ops' : ''; qIndex.push(`CREATE INDEX if not exists ${name} ON ${el.nspname}.${el.relname} USING ${indexUsing} (${el.aname} ${suffix})`); if (isGin) { qIndex.push(`CREATE INDEX if not exists ${name}_lower ON ${el.nspname}.${el.relname} USING ${indexUsing} (lower(${el.aname}) ${suffix})`); } if (indexUsing === 'gist') { qIndex.push(`CREATE INDEX if not exists ${name.replace('gist', 'gist1')} ON ${el.nspname}.${el.relname} USING gist (${el.aname})`); qIndex.push(`CREATE INDEX if not exists ${name.replace('gist', 'area')} ON ${el.nspname}.${el.relname} USING btree (st_area(st_transform(${el.aname},3857)))`); qIndex.push(`CREATE INDEX if not exists ${name.replace('gist', 'area_true')} ON ${el.nspname}.${el.relname} USING btree (st_area(${el.aname}, true))`); qIndex.push(`CREATE INDEX if not exists ${name.replace('gist', '4326')} ON ${el.nspname}.${el.relname} USING gist (st_transform(${el.aname},4326))`); } } } loadedIndex[redisKey] = 1; // throw qIndex; if (!qIndex.length) return null; if (config.local) { // console.log(qIndex.filter((v, i, a) => a.indexOf(v) === i)); } // logger.file('index', { table, filter, sql: qIndex.filter((v, i, a) => a.indexOf(v) === i) }); qIndex.filter((v, i, a) => a.indexOf(v) === i).map((el) => pg.one(el).catch((err) => console.log(err.toString()))); return 'ok'; } export default autoIndex;