import pg_promise from"pg-promise";import StorageInterface from"../interface.js";import Document from"../../document.js";import{concat,toArray}from"../../common.js";const defaults={schema:"flexsearch",user:"postgres",pass:"postgres",name:"postgres",host:"localhost",port:"5432"},pgp=pg_promise(),VERSION=1,MAXIMUM_QUERY_VARS=16000,fields=["map","ctx","reg","tag","cfg"],types={text:"text",char:"text",varchar:"text",string:"text",number:"int",numeric:"int",integer:"int",smallint:"int",tinyint:"int",mediumint:"int",int:"int",int8:"int",uint8:"int",int16:"int",uint16:"int",int32:"int",uint32:"bigint",int64:"bigint",bigint:"bigint"};function sanitize(a){return a.toLowerCase().replace(/[^a-z0-9_]/g,"")}let DB,TRX;export default function PostgresDB(a,b={}){if(!(this instanceof PostgresDB))return new PostgresDB(a,b);if("object"==typeof a&&(a=a.name,b=a),a||console.info("Default storage space was used, because a name was not passed."),this.id=(b.schema?sanitize(b.schema):defaults.schema)+(a?"_"+sanitize(a):""),this.field=b.field?"_"+sanitize(b.field):"",this.type=b.type?types[b.type.toLowerCase()]:"text",this.support_tag_search=!0,!this.type)throw new Error("Unknown type of ID '"+b.type+"'");this.db=DB||(DB=b.db||null),Object.assign(defaults,b),this.db&&delete defaults.db}PostgresDB.prototype.mount=function(a){return a instanceof Document?a.mount(this):(a.db=this,this.open())},PostgresDB.prototype.open=async function(){this.db||(this.db=DB||(DB=pgp(`postgres://${defaults.user}:${encodeURIComponent(defaults.pass)}@${defaults.host}:${defaults.port}/${defaults.name}`)));const a=await this.db.oneOrNone(` SELECT EXISTS ( SELECT 1 FROM information_schema.schemata WHERE schema_name = '${this.id}' ); `);a&&a.exists||(await this.db.none(`CREATE SCHEMA IF NOT EXISTS ${this.id};`));for(let a=0;a{});break;case"cfg":await this.db.none(` CREATE TABLE IF NOT EXISTS ${this.id}.cfg${this.field}( cfg text NOT NULL ); `);}}return this.db},PostgresDB.prototype.close=function(){return this.db.close&&this.db.close(),this.db=DB=null,this},PostgresDB.prototype.destroy=async function(){await this.db.none(` DROP TABLE IF EXISTS ${this.id}.map${this.field}; DROP TABLE IF EXISTS ${this.id}.ctx${this.field}; DROP TABLE IF EXISTS ${this.id}.tag${this.field}; DROP TABLE IF EXISTS ${this.id}.cfg${this.field}; DROP TABLE IF EXISTS ${this.id}.reg; `),this.close()},PostgresDB.prototype.clear=function(){return this.db.none(` TRUNCATE TABLE ${this.id}.map${this.field}; TRUNCATE TABLE ${this.id}.ctx${this.field}; TRUNCATE TABLE ${this.id}.tag${this.field}; TRUNCATE TABLE ${this.id}.cfg${this.field}; TRUNCATE TABLE ${this.id}.reg; `)};function create_result(a,b,c){if(b){for(let b=0;bMAXIMUM_QUERY_VARS?a.slice(c,c+MAXIMUM_QUERY_VARS):c?a.slice(c):a;c+=d.length;let e="";for(let a=1;a<=d.length;a++)e+=(e?",":"")+"$"+a;const f=await this.db.any(` SELECT id, doc FROM ${this.id}.reg WHERE id IN (${e})`,a);if(f&&f.length){for(let a,b=0;bm;k+=(k?" OR ":"")+`(ctx = $${n++} AND key = $${n++})`,l.push(d?j:m,d?m:j),m=j}if(h){k="("+k+")";for(let a=0;a