Sindbad~EG File Manager

Current Path : /home/infinitibizsol/.trash/node_modules.2/sequelize/lib/dialects/postgres/
Upload File :
Current File : /home/infinitibizsol/.trash/node_modules.2/sequelize/lib/dialects/postgres/query-generator.js.map

{
  "version": 3,
  "sources": ["../../../src/dialects/postgres/query-generator.js"],
  "sourcesContent": ["'use strict';\n\nconst Utils = require('../../utils');\nconst util = require('util');\nconst DataTypes = require('../../data-types');\nconst AbstractQueryGenerator = require('../abstract/query-generator');\nconst semver = require('semver');\nconst _ = require('lodash');\n\n/**\n * list of reserved words in PostgreSQL 10\n * source: https://www.postgresql.org/docs/10/static/sql-keywords-appendix.html\n *\n * @private\n */\nconst POSTGRES_RESERVED_WORDS = 'all,analyse,analyze,and,any,array,as,asc,asymmetric,authorization,binary,both,case,cast,check,collate,collation,column,concurrently,constraint,create,cross,current_catalog,current_date,current_role,current_schema,current_time,current_timestamp,current_user,default,deferrable,desc,distinct,do,else,end,except,false,fetch,for,foreign,freeze,from,full,grant,group,having,ilike,in,initially,inner,intersect,into,is,isnull,join,lateral,leading,left,like,limit,localtime,localtimestamp,natural,not,notnull,null,offset,on,only,or,order,outer,overlaps,placing,primary,references,returning,right,select,session_user,similar,some,symmetric,table,tablesample,then,to,trailing,true,union,unique,user,using,variadic,verbose,when,where,window,with'.split(',');\n\nclass PostgresQueryGenerator extends AbstractQueryGenerator {\n  setSearchPath(searchPath) {\n    return `SET search_path to ${searchPath};`;\n  }\n\n  createDatabaseQuery(databaseName, options) {\n    options = {\n      encoding: null,\n      collate: null,\n      ...options\n    };\n\n    const values = {\n      database: this.quoteTable(databaseName),\n      encoding: options.encoding ? ` ENCODING = ${this.escape(options.encoding)}` : '',\n      collation: options.collate ? ` LC_COLLATE = ${this.escape(options.collate)}` : '',\n      ctype: options.ctype ? ` LC_CTYPE = ${this.escape(options.ctype)}` : '',\n      template: options.template ? ` TEMPLATE = ${this.escape(options.template)}` : ''\n    };\n\n    return `CREATE DATABASE ${values.database}${values.encoding}${values.collation}${values.ctype}${values.template};`;\n  }\n\n  dropDatabaseQuery(databaseName) {\n    return `DROP DATABASE IF EXISTS ${this.quoteTable(databaseName)};`;\n  }\n\n  createSchema(schema) {\n    const databaseVersion = _.get(this, 'sequelize.options.databaseVersion', 0);\n\n    if (databaseVersion && semver.gte(databaseVersion, '9.2.0')) {\n      return `CREATE SCHEMA IF NOT EXISTS ${this.quoteIdentifier(schema)};`;\n    }\n\n    return `CREATE SCHEMA ${this.quoteIdentifier(schema)};`;\n  }\n\n  dropSchema(schema) {\n    return `DROP SCHEMA IF EXISTS ${this.quoteIdentifier(schema)} CASCADE;`;\n  }\n\n  showSchemasQuery() {\n    return \"SELECT schema_name FROM information_schema.schemata WHERE schema_name <> 'information_schema' AND schema_name != 'public' AND schema_name !~ E'^pg_';\";\n  }\n\n  versionQuery() {\n    return 'SHOW SERVER_VERSION';\n  }\n\n  createTableQuery(tableName, attributes, options) {\n    options = { ...options };\n\n    //Postgres 9.0 does not support CREATE TABLE IF NOT EXISTS, 9.1 and above do\n    const databaseVersion = _.get(this, 'sequelize.options.databaseVersion', 0);\n    const attrStr = [];\n    let comments = '';\n    let columnComments = '';\n\n    const quotedTable = this.quoteTable(tableName);\n\n    if (options.comment && typeof options.comment === 'string') {\n      comments += `; COMMENT ON TABLE ${quotedTable} IS ${this.escape(options.comment)}`;\n    }\n\n    for (const attr in attributes) {\n      const quotedAttr = this.quoteIdentifier(attr);\n      const i = attributes[attr].indexOf('COMMENT ');\n      if (i !== -1) {\n        // Move comment to a separate query\n        const escapedCommentText = this.escape(attributes[attr].substring(i + 8));\n        columnComments += `; COMMENT ON COLUMN ${quotedTable}.${quotedAttr} IS ${escapedCommentText}`;\n        attributes[attr] = attributes[attr].substring(0, i);\n      }\n\n      const dataType = this.dataTypeMapping(tableName, attr, attributes[attr]);\n      attrStr.push(`${quotedAttr} ${dataType}`);\n    }\n\n\n    let attributesClause = attrStr.join(', ');\n\n    if (options.uniqueKeys) {\n      _.each(options.uniqueKeys, columns => {\n        if (columns.customIndex) {\n          attributesClause += `, UNIQUE (${columns.fields.map(field => this.quoteIdentifier(field)).join(', ')})`;\n        }\n      });\n    }\n\n    const pks = _.reduce(attributes, (acc, attribute, key) => {\n      if (attribute.includes('PRIMARY KEY')) {\n        acc.push(this.quoteIdentifier(key));\n      }\n      return acc;\n    }, []).join(',');\n\n    if (pks.length > 0) {\n      attributesClause += `, PRIMARY KEY (${pks})`;\n    }\n\n    return `CREATE TABLE ${databaseVersion === 0 || semver.gte(databaseVersion, '9.1.0') ? 'IF NOT EXISTS ' : ''}${quotedTable} (${attributesClause})${comments}${columnComments};`;\n  }\n\n  dropTableQuery(tableName, options) {\n    options = options || {};\n    return `DROP TABLE IF EXISTS ${this.quoteTable(tableName)}${options.cascade ? ' CASCADE' : ''};`;\n  }\n\n  showTablesQuery() {\n    const schema = this.options.schema || 'public';\n\n    return `SELECT table_name FROM information_schema.tables WHERE table_schema = ${this.escape(schema)} AND table_type LIKE '%TABLE' AND table_name != 'spatial_ref_sys';`;\n  }\n\n  tableExistsQuery(tableName) {\n    const table = tableName.tableName || tableName;\n    const schema = tableName.schema || 'public';\n\n    return `SELECT table_name FROM information_schema.tables WHERE table_schema = ${this.escape(schema)} AND table_name = ${this.escape(table)}`;\n  }\n\n  describeTableQuery(tableName, schema) {\n    schema = schema || this.options.schema || 'public';\n\n    return 'SELECT ' +\n      'pk.constraint_type as \"Constraint\",' +\n      'c.column_name as \"Field\", ' +\n      'c.column_default as \"Default\",' +\n      'c.is_nullable as \"Null\", ' +\n      '(CASE WHEN c.udt_name = \\'hstore\\' THEN c.udt_name ELSE c.data_type END) || (CASE WHEN c.character_maximum_length IS NOT NULL THEN \\'(\\' || c.character_maximum_length || \\')\\' ELSE \\'\\' END) as \"Type\", ' +\n      '(SELECT array_agg(e.enumlabel) FROM pg_catalog.pg_type t JOIN pg_catalog.pg_enum e ON t.oid=e.enumtypid WHERE t.typname=c.udt_name) AS \"special\", ' +\n      '(SELECT pgd.description FROM pg_catalog.pg_statio_all_tables AS st INNER JOIN pg_catalog.pg_description pgd on (pgd.objoid=st.relid) WHERE c.ordinal_position=pgd.objsubid AND c.table_name=st.relname) AS \"Comment\" ' +\n      'FROM information_schema.columns c ' +\n      'LEFT JOIN (SELECT tc.table_schema, tc.table_name, ' +\n      'cu.column_name, tc.constraint_type ' +\n      'FROM information_schema.TABLE_CONSTRAINTS tc ' +\n      'JOIN information_schema.KEY_COLUMN_USAGE  cu ' +\n      'ON tc.table_schema=cu.table_schema and tc.table_name=cu.table_name ' +\n      'and tc.constraint_name=cu.constraint_name ' +\n      'and tc.constraint_type=\\'PRIMARY KEY\\') pk ' +\n      'ON pk.table_schema=c.table_schema ' +\n      'AND pk.table_name=c.table_name ' +\n      'AND pk.column_name=c.column_name ' +\n      `WHERE c.table_name = ${this.escape(tableName)} AND c.table_schema = ${this.escape(schema)}`;\n  }\n\n  /**\n   * Check whether the statmement is json function or simple path\n   *\n   * @param   {string}  stmt  The statement to validate\n   * @returns {boolean}       true if the given statement is json function\n   * @throws  {Error}         throw if the statement looks like json function but has invalid token\n   */\n  _checkValidJsonStatement(stmt) {\n    if (typeof stmt !== 'string') {\n      return false;\n    }\n\n    // https://www.postgresql.org/docs/current/static/functions-json.html\n    const jsonFunctionRegex = /^\\s*((?:[a-z]+_){0,2}jsonb?(?:_[a-z]+){0,2})\\([^)]*\\)/i;\n    const jsonOperatorRegex = /^\\s*(->>?|#>>?|@>|<@|\\?[|&]?|\\|{2}|#-)/i;\n    const tokenCaptureRegex = /^\\s*((?:([`\"'])(?:(?!\\2).|\\2{2})*\\2)|[\\w\\d\\s]+|[().,;+-])/i;\n\n    let currentIndex = 0;\n    let openingBrackets = 0;\n    let closingBrackets = 0;\n    let hasJsonFunction = false;\n    let hasInvalidToken = false;\n\n    while (currentIndex < stmt.length) {\n      const string = stmt.substr(currentIndex);\n      const functionMatches = jsonFunctionRegex.exec(string);\n      if (functionMatches) {\n        currentIndex += functionMatches[0].indexOf('(');\n        hasJsonFunction = true;\n        continue;\n      }\n\n      const operatorMatches = jsonOperatorRegex.exec(string);\n      if (operatorMatches) {\n        currentIndex += operatorMatches[0].length;\n        hasJsonFunction = true;\n        continue;\n      }\n\n      const tokenMatches = tokenCaptureRegex.exec(string);\n      if (tokenMatches) {\n        const capturedToken = tokenMatches[1];\n        if (capturedToken === '(') {\n          openingBrackets++;\n        } else if (capturedToken === ')') {\n          closingBrackets++;\n        } else if (capturedToken === ';') {\n          hasInvalidToken = true;\n          break;\n        }\n        currentIndex += tokenMatches[0].length;\n        continue;\n      }\n\n      break;\n    }\n\n    // Check invalid json statement\n    hasInvalidToken |= openingBrackets !== closingBrackets;\n    if (hasJsonFunction && hasInvalidToken) {\n      throw new Error(`Invalid json statement: ${stmt}`);\n    }\n\n    // return true if the statement has valid json function\n    return hasJsonFunction;\n  }\n\n  handleSequelizeMethod(smth, tableName, factory, options, prepend) {\n    if (smth instanceof Utils.Json) {\n      // Parse nested object\n      if (smth.conditions) {\n        const conditions = this.parseConditionObject(smth.conditions).map(condition =>\n          `${this.jsonPathExtractionQuery(condition.path[0], _.tail(condition.path))} = '${condition.value}'`\n        );\n\n        return conditions.join(' AND ');\n      }\n      if (smth.path) {\n        let str;\n\n        // Allow specifying conditions using the postgres json syntax\n        if (this._checkValidJsonStatement(smth.path)) {\n          str = smth.path;\n        } else {\n          // Also support json property accessors\n          const paths = _.toPath(smth.path);\n          const column = paths.shift();\n          str = this.jsonPathExtractionQuery(column, paths);\n        }\n\n        if (smth.value) {\n          str += util.format(' = %s', this.escape(smth.value));\n        }\n\n        return str;\n      }\n    }\n    return super.handleSequelizeMethod.call(this, smth, tableName, factory, options, prepend);\n  }\n\n  addColumnQuery(table, key, attribute) {\n    const dbDataType = this.attributeToSQL(attribute, { context: 'addColumn', table, key });\n    const dataType = attribute.type || attribute;\n    const definition = this.dataTypeMapping(table, key, dbDataType);\n    const quotedKey = this.quoteIdentifier(key);\n    const quotedTable = this.quoteTable(this.extractTableDetails(table));\n\n    let query = `ALTER TABLE ${quotedTable} ADD COLUMN ${quotedKey} ${definition};`;\n\n    if (dataType instanceof DataTypes.ENUM) {\n      query = this.pgEnum(table, key, dataType) + query;\n    } else if (dataType.type && dataType.type instanceof DataTypes.ENUM) {\n      query = this.pgEnum(table, key, dataType.type) + query;\n    }\n\n    return query;\n  }\n\n  removeColumnQuery(tableName, attributeName) {\n    const quotedTableName = this.quoteTable(this.extractTableDetails(tableName));\n    const quotedAttributeName = this.quoteIdentifier(attributeName);\n    return `ALTER TABLE ${quotedTableName} DROP COLUMN ${quotedAttributeName};`;\n  }\n\n  changeColumnQuery(tableName, attributes) {\n    const query = subQuery => `ALTER TABLE ${this.quoteTable(tableName)} ALTER COLUMN ${subQuery};`;\n    const sql = [];\n    for (const attributeName in attributes) {\n      let definition = this.dataTypeMapping(tableName, attributeName, attributes[attributeName]);\n      let attrSql = '';\n\n      if (definition.includes('NOT NULL')) {\n        attrSql += query(`${this.quoteIdentifier(attributeName)} SET NOT NULL`);\n\n        definition = definition.replace('NOT NULL', '').trim();\n      } else if (!definition.includes('REFERENCES')) {\n        attrSql += query(`${this.quoteIdentifier(attributeName)} DROP NOT NULL`);\n      }\n\n      if (definition.includes('DEFAULT')) {\n        attrSql += query(`${this.quoteIdentifier(attributeName)} SET DEFAULT ${definition.match(/DEFAULT ([^;]+)/)[1]}`);\n\n        definition = definition.replace(/(DEFAULT[^;]+)/, '').trim();\n      } else if (!definition.includes('REFERENCES')) {\n        attrSql += query(`${this.quoteIdentifier(attributeName)} DROP DEFAULT`);\n      }\n\n      if (attributes[attributeName].startsWith('ENUM(')) {\n        attrSql += this.pgEnum(tableName, attributeName, attributes[attributeName]);\n        definition = definition.replace(/^ENUM\\(.+\\)/, this.pgEnumName(tableName, attributeName, { schema: false }));\n        definition += ` USING (${this.quoteIdentifier(attributeName)}::${this.pgEnumName(tableName, attributeName)})`;\n      }\n\n      if (definition.match(/UNIQUE;*$/)) {\n        definition = definition.replace(/UNIQUE;*$/, '');\n        attrSql += query(`ADD UNIQUE (${this.quoteIdentifier(attributeName)})`).replace('ALTER COLUMN', '');\n      }\n\n      if (definition.includes('REFERENCES')) {\n        definition = definition.replace(/.+?(?=REFERENCES)/, '');\n        attrSql += query(`ADD FOREIGN KEY (${this.quoteIdentifier(attributeName)}) ${definition}`).replace('ALTER COLUMN', '');\n      } else {\n        attrSql += query(`${this.quoteIdentifier(attributeName)} TYPE ${definition}`);\n      }\n\n      sql.push(attrSql);\n    }\n\n    return sql.join('');\n  }\n\n  renameColumnQuery(tableName, attrBefore, attributes) {\n\n    const attrString = [];\n\n    for (const attributeName in attributes) {\n      attrString.push(`${this.quoteIdentifier(attrBefore)} TO ${this.quoteIdentifier(attributeName)}`);\n    }\n\n    return `ALTER TABLE ${this.quoteTable(tableName)} RENAME COLUMN ${attrString.join(', ')};`;\n  }\n\n  fn(fnName, tableName, parameters, body, returns, language) {\n    fnName = fnName || 'testfunc';\n    language = language || 'plpgsql';\n    returns = returns ? `RETURNS ${returns}` : '';\n    parameters = parameters || '';\n\n    return `CREATE OR REPLACE FUNCTION pg_temp.${fnName}(${parameters}) ${returns} AS $func$ BEGIN ${body} END; $func$ LANGUAGE ${language}; SELECT * FROM pg_temp.${fnName}();`;\n  }\n\n  truncateTableQuery(tableName, options = {}) {\n    return [\n      `TRUNCATE ${this.quoteTable(tableName)}`,\n      options.restartIdentity ? ' RESTART IDENTITY' : '',\n      options.cascade ? ' CASCADE' : ''\n    ].join('');\n  }\n\n  deleteQuery(tableName, where, options = {}, model) {\n    const table = this.quoteTable(tableName);\n    let whereClause = this.getWhereConditions(where, null, model, options);\n    const limit = options.limit ? ` LIMIT ${this.escape(options.limit)}` : '';\n    let primaryKeys = '';\n    let primaryKeysSelection = '';\n\n    if (whereClause) {\n      whereClause = ` WHERE ${whereClause}`;\n    }\n\n    if (options.limit) {\n      if (!model) {\n        throw new Error('Cannot LIMIT delete without a model.');\n      }\n\n      const pks = Object.values(model.primaryKeys).map(pk => this.quoteIdentifier(pk.field)).join(',');\n\n      primaryKeys = model.primaryKeyAttributes.length > 1 ? `(${pks})` : pks;\n      primaryKeysSelection = pks;\n\n      return `DELETE FROM ${table} WHERE ${primaryKeys} IN (SELECT ${primaryKeysSelection} FROM ${table}${whereClause}${limit})`;\n    }\n    return `DELETE FROM ${table}${whereClause}`;\n  }\n\n  showIndexesQuery(tableName) {\n    let schemaJoin = '';\n    let schemaWhere = '';\n    if (typeof tableName !== 'string') {\n      schemaJoin = ', pg_namespace s';\n      schemaWhere = ` AND s.oid = t.relnamespace AND s.nspname = '${tableName.schema}'`;\n      tableName = tableName.tableName;\n    }\n\n    // This is ARCANE!\n    return 'SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, ' +\n      'array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) ' +\n      `AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a${schemaJoin} ` +\n      'WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND ' +\n      `t.relkind = 'r' and t.relname = '${tableName}'${schemaWhere} ` +\n      'GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;';\n  }\n\n  showConstraintsQuery(tableName) {\n    //Postgres converts camelCased alias to lowercase unless quoted\n    return [\n      'SELECT constraint_catalog AS \"constraintCatalog\",',\n      'constraint_schema AS \"constraintSchema\",',\n      'constraint_name AS \"constraintName\",',\n      'table_catalog AS \"tableCatalog\",',\n      'table_schema AS \"tableSchema\",',\n      'table_name AS \"tableName\",',\n      'constraint_type AS \"constraintType\",',\n      'is_deferrable AS \"isDeferrable\",',\n      'initially_deferred AS \"initiallyDeferred\"',\n      'from INFORMATION_SCHEMA.table_constraints',\n      `WHERE table_name='${tableName}';`\n    ].join(' ');\n  }\n\n  removeIndexQuery(tableName, indexNameOrAttributes, options) {\n    let indexName = indexNameOrAttributes;\n\n    if (typeof indexName !== 'string') {\n      indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join('_')}`);\n    }\n\n    return [\n      'DROP INDEX',\n      options && options.concurrently && 'CONCURRENTLY',\n      `IF EXISTS ${this.quoteIdentifiers(indexName)}`\n    ].filter(Boolean).join(' ');\n  }\n\n  addLimitAndOffset(options) {\n    let fragment = '';\n    /* eslint-disable */\n    if (options.limit != null) {\n      fragment += ' LIMIT ' + this.escape(options.limit);\n    }\n    if (options.offset != null) {\n      fragment += ' OFFSET ' + this.escape(options.offset);\n    }\n    /* eslint-enable */\n\n    return fragment;\n  }\n\n  attributeToSQL(attribute, options) {\n    if (!_.isPlainObject(attribute)) {\n      attribute = {\n        type: attribute\n      };\n    }\n\n    let type;\n    if (\n      attribute.type instanceof DataTypes.ENUM ||\n      attribute.type instanceof DataTypes.ARRAY && attribute.type.type instanceof DataTypes.ENUM\n    ) {\n      const enumType = attribute.type.type || attribute.type;\n      let values = attribute.values;\n\n      if (enumType.values && !attribute.values) {\n        values = enumType.values;\n      }\n\n      if (Array.isArray(values) && values.length > 0) {\n        type = `ENUM(${values.map(value => this.escape(value)).join(', ')})`;\n\n        if (attribute.type instanceof DataTypes.ARRAY) {\n          type += '[]';\n        }\n\n      } else {\n        throw new Error(\"Values for ENUM haven't been defined.\");\n      }\n    }\n\n    if (!type) {\n      type = attribute.type;\n    }\n\n    let sql = type.toString();\n\n    if (Object.prototype.hasOwnProperty.call(attribute, 'allowNull') && !attribute.allowNull) {\n      sql += ' NOT NULL';\n    }\n\n    if (attribute.autoIncrement) {\n      if (attribute.autoIncrementIdentity) {\n        sql += ' GENERATED BY DEFAULT AS IDENTITY';\n      } else {\n        sql += ' SERIAL';\n      }\n    }\n\n    if (Utils.defaultValueSchemable(attribute.defaultValue)) {\n      sql += ` DEFAULT ${this.escape(attribute.defaultValue, attribute)}`;\n    }\n\n    if (attribute.unique === true) {\n      sql += ' UNIQUE';\n    }\n\n    if (attribute.primaryKey) {\n      sql += ' PRIMARY KEY';\n    }\n\n    if (attribute.references) {\n      let referencesTable = this.quoteTable(attribute.references.model);\n      let schema;\n\n      if (options.schema) {\n        schema = options.schema;\n      } else if (\n        (!attribute.references.model || typeof attribute.references.model == 'string')\n        && options.table\n        && options.table.schema\n      ) {\n        schema = options.table.schema;\n      }\n\n      if (schema) {\n        referencesTable = this.quoteTable(this.addSchema({\n          tableName: referencesTable,\n          _schema: schema\n        }));\n      }\n\n      let referencesKey;\n\n      if (!options.withoutForeignKeyConstraints) {\n        if (attribute.references.key) {\n          referencesKey = this.quoteIdentifiers(attribute.references.key);\n        } else {\n          referencesKey = this.quoteIdentifier('id');\n        }\n\n        sql += ` REFERENCES ${referencesTable} (${referencesKey})`;\n\n        if (attribute.onDelete) {\n          sql += ` ON DELETE ${attribute.onDelete.toUpperCase()}`;\n        }\n\n        if (attribute.onUpdate) {\n          sql += ` ON UPDATE ${attribute.onUpdate.toUpperCase()}`;\n        }\n\n        if (attribute.references.deferrable) {\n          sql += ` ${attribute.references.deferrable.toString(this)}`;\n        }\n      }\n    }\n\n    if (attribute.comment && typeof attribute.comment === 'string') {\n      if (options && ['addColumn', 'changeColumn'].includes(options.context)) {\n        const quotedAttr = this.quoteIdentifier(options.key);\n        const escapedCommentText = this.escape(attribute.comment);\n        sql += `; COMMENT ON COLUMN ${this.quoteTable(options.table)}.${quotedAttr} IS ${escapedCommentText}`;\n      } else {\n        // for createTable event which does it's own parsing\n        // TODO: centralize creation of comment statements here\n        sql += ` COMMENT ${attribute.comment}`;\n      }\n    }\n\n    return sql;\n  }\n\n  deferConstraintsQuery(options) {\n    return options.deferrable.toString(this);\n  }\n\n  setConstraintQuery(columns, type) {\n    let columnFragment = 'ALL';\n\n    if (columns) {\n      columnFragment = columns.map(column => this.quoteIdentifier(column)).join(', ');\n    }\n\n    return `SET CONSTRAINTS ${columnFragment} ${type}`;\n  }\n\n  setDeferredQuery(columns) {\n    return this.setConstraintQuery(columns, 'DEFERRED');\n  }\n\n  setImmediateQuery(columns) {\n    return this.setConstraintQuery(columns, 'IMMEDIATE');\n  }\n\n  attributesToSQL(attributes, options) {\n    const result = {};\n\n    for (const key in attributes) {\n      const attribute = attributes[key];\n      result[attribute.field || key] = this.attributeToSQL(attribute, { key, ...options });\n    }\n\n    return result;\n  }\n\n  createTrigger(tableName, triggerName, eventType, fireOnSpec, functionName, functionParams, optionsArray) {\n    const decodedEventType = this.decodeTriggerEventType(eventType);\n    const eventSpec = this.expandTriggerEventSpec(fireOnSpec);\n    const expandedOptions = this.expandOptions(optionsArray);\n    const paramList = this._expandFunctionParamList(functionParams);\n\n    return `CREATE ${this.triggerEventTypeIsConstraint(eventType)}TRIGGER ${this.quoteIdentifier(triggerName)} ${decodedEventType} ${\n      eventSpec} ON ${this.quoteTable(tableName)}${expandedOptions ? ` ${expandedOptions}` : ''} EXECUTE PROCEDURE ${functionName}(${paramList});`;\n  }\n\n  dropTrigger(tableName, triggerName) {\n    return `DROP TRIGGER ${this.quoteIdentifier(triggerName)} ON ${this.quoteTable(tableName)} RESTRICT;`;\n  }\n\n  renameTrigger(tableName, oldTriggerName, newTriggerName) {\n    return `ALTER TRIGGER ${this.quoteIdentifier(oldTriggerName)} ON ${this.quoteTable(tableName)} RENAME TO ${this.quoteIdentifier(newTriggerName)};`;\n  }\n\n  createFunction(functionName, params, returnType, language, body, optionsArray, options) {\n    if (!functionName || !returnType || !language || !body) throw new Error('createFunction missing some parameters. Did you pass functionName, returnType, language and body?');\n\n    const paramList = this._expandFunctionParamList(params);\n    const variableList = options && options.variables ? this._expandFunctionVariableList(options.variables) : '';\n    const expandedOptionsArray = this.expandOptions(optionsArray);\n\n    const statement = options && options.force ? 'CREATE OR REPLACE FUNCTION' : 'CREATE FUNCTION';\n\n    return `${statement} ${functionName}(${paramList}) RETURNS ${returnType} AS $func$ ${variableList} BEGIN ${body} END; $func$ language '${language}'${expandedOptionsArray};`;\n  }\n\n  dropFunction(functionName, params) {\n    if (!functionName) throw new Error('requires functionName');\n    // RESTRICT is (currently, as of 9.2) default but we'll be explicit\n    const paramList = this._expandFunctionParamList(params);\n    return `DROP FUNCTION ${functionName}(${paramList}) RESTRICT;`;\n  }\n\n  renameFunction(oldFunctionName, params, newFunctionName) {\n    const paramList = this._expandFunctionParamList(params);\n    return `ALTER FUNCTION ${oldFunctionName}(${paramList}) RENAME TO ${newFunctionName};`;\n  }\n\n  pgEscapeAndQuote(val) {\n    return this.quoteIdentifier(Utils.removeTicks(this.escape(val), \"'\"));\n  }\n\n  _expandFunctionParamList(params) {\n    if (params === undefined || !Array.isArray(params)) {\n      throw new Error('_expandFunctionParamList: function parameters array required, including an empty one for no arguments');\n    }\n\n    const paramList = [];\n    params.forEach(curParam => {\n      const paramDef = [];\n      if (curParam.type) {\n        if (curParam.direction) { paramDef.push(curParam.direction); }\n        if (curParam.name) { paramDef.push(curParam.name); }\n        paramDef.push(curParam.type);\n      } else {\n        throw new Error('function or trigger used with a parameter without any type');\n      }\n\n      const joined = paramDef.join(' ');\n      if (joined) paramList.push(joined);\n\n    });\n\n    return paramList.join(', ');\n  }\n\n  _expandFunctionVariableList(variables) {\n    if (!Array.isArray(variables)) {\n      throw new Error('_expandFunctionVariableList: function variables must be an array');\n    }\n    const variableDefinitions = [];\n    variables.forEach(variable => {\n      if (!variable.name || !variable.type) {\n        throw new Error('function variable must have a name and type');\n      }\n      let variableDefinition = `DECLARE ${variable.name} ${variable.type}`;\n      if (variable.default) {\n        variableDefinition += ` := ${variable.default}`;\n      }\n      variableDefinition += ';';\n      variableDefinitions.push(variableDefinition);\n    });\n    return variableDefinitions.join(' ');\n  }\n\n  expandOptions(options) {\n    return options === undefined || _.isEmpty(options) ?\n      '' : options.join(' ');\n  }\n\n  decodeTriggerEventType(eventSpecifier) {\n    const EVENT_DECODER = {\n      'after': 'AFTER',\n      'before': 'BEFORE',\n      'instead_of': 'INSTEAD OF',\n      'after_constraint': 'AFTER'\n    };\n\n    if (!EVENT_DECODER[eventSpecifier]) {\n      throw new Error(`Invalid trigger event specified: ${eventSpecifier}`);\n    }\n\n    return EVENT_DECODER[eventSpecifier];\n  }\n\n  triggerEventTypeIsConstraint(eventSpecifier) {\n    return eventSpecifier === 'after_constraint' ? 'CONSTRAINT ' : '';\n  }\n\n  expandTriggerEventSpec(fireOnSpec) {\n    if (_.isEmpty(fireOnSpec)) {\n      throw new Error('no table change events specified to trigger on');\n    }\n\n    return _.map(fireOnSpec, (fireValue, fireKey) => {\n      const EVENT_MAP = {\n        'insert': 'INSERT',\n        'update': 'UPDATE',\n        'delete': 'DELETE',\n        'truncate': 'TRUNCATE'\n      };\n\n      if (!EVENT_MAP[fireValue]) {\n        throw new Error(`parseTriggerEventSpec: undefined trigger event ${fireKey}`);\n      }\n\n      let eventSpec = EVENT_MAP[fireValue];\n      if (eventSpec === 'UPDATE') {\n        if (Array.isArray(fireValue) && fireValue.length > 0) {\n          eventSpec += ` OF ${fireValue.join(', ')}`;\n        }\n      }\n\n      return eventSpec;\n    }).join(' OR ');\n  }\n\n  pgEnumName(tableName, attr, options) {\n    options = options || {};\n\n    const tableDetails = this.extractTableDetails(tableName, options);\n    let enumName = Utils.addTicks(Utils.generateEnumName(tableDetails.tableName, attr), '\"');\n\n    // pgListEnums requires the enum name only, without the schema\n    if (options.schema !== false && tableDetails.schema) {\n      enumName = this.quoteIdentifier(tableDetails.schema) + tableDetails.delimiter + enumName;\n    }\n\n    return enumName;\n  }\n\n  pgListEnums(tableName, attrName, options) {\n    let enumName = '';\n    const tableDetails = this.extractTableDetails(tableName, options);\n\n    if (tableDetails.tableName && attrName) {\n      enumName = ` AND t.typname=${this.pgEnumName(tableDetails.tableName, attrName, { schema: false }).replace(/\"/g, \"'\")}`;\n    }\n\n    return 'SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t ' +\n      'JOIN pg_enum e ON t.oid = e.enumtypid ' +\n      'JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace ' +\n      `WHERE n.nspname = '${tableDetails.schema}'${enumName} GROUP BY 1`;\n  }\n\n  pgEnum(tableName, attr, dataType, options) {\n    const enumName = this.pgEnumName(tableName, attr, options);\n    let values;\n\n    if (dataType.values) {\n      values = `ENUM(${dataType.values.map(value => this.escape(value)).join(', ')})`;\n    } else {\n      values = dataType.toString().match(/^ENUM\\(.+\\)/)[0];\n    }\n\n    let sql = `DO ${this.escape(`BEGIN CREATE TYPE ${enumName} AS ${values}; EXCEPTION WHEN duplicate_object THEN null; END`)};`;\n    if (!!options && options.force === true) {\n      sql = this.pgEnumDrop(tableName, attr) + sql;\n    }\n    return sql;\n  }\n\n  pgEnumAdd(tableName, attr, value, options) {\n    const enumName = this.pgEnumName(tableName, attr);\n    let sql = `ALTER TYPE ${enumName} ADD VALUE `;\n\n    if (semver.gte(this.sequelize.options.databaseVersion, '9.3.0')) {\n      sql += 'IF NOT EXISTS ';\n    }\n    sql += this.escape(value);\n\n    if (options.before) {\n      sql += ` BEFORE ${this.escape(options.before)}`;\n    } else if (options.after) {\n      sql += ` AFTER ${this.escape(options.after)}`;\n    }\n\n    return sql;\n  }\n\n  pgEnumDrop(tableName, attr, enumName) {\n    enumName = enumName || this.pgEnumName(tableName, attr);\n    return `DROP TYPE IF EXISTS ${enumName}; `;\n  }\n\n  fromArray(text) {\n    text = text.replace(/^{/, '').replace(/}$/, '');\n    let matches = text.match(/(\"(?:\\\\.|[^\"\\\\\\\\])*\"|[^,]*)(?:\\s*,\\s*|\\s*$)/ig);\n\n    if (matches.length < 1) {\n      return [];\n    }\n\n    matches = matches.map(m => m.replace(/\",$/, '').replace(/,$/, '').replace(/(^\"|\"$)/g, ''));\n\n    return matches.slice(0, -1);\n  }\n\n  dataTypeMapping(tableName, attr, dataType) {\n    if (dataType.includes('PRIMARY KEY')) {\n      dataType = dataType.replace('PRIMARY KEY', '');\n    }\n\n    if (dataType.includes('SERIAL')) {\n      if (dataType.includes('BIGINT')) {\n        dataType = dataType.replace('SERIAL', 'BIGSERIAL');\n        dataType = dataType.replace('BIGINT', '');\n      } else if (dataType.includes('SMALLINT')) {\n        dataType = dataType.replace('SERIAL', 'SMALLSERIAL');\n        dataType = dataType.replace('SMALLINT', '');\n      } else {\n        dataType = dataType.replace('INTEGER', '');\n      }\n      dataType = dataType.replace('NOT NULL', '');\n    }\n\n    if (dataType.startsWith('ENUM(')) {\n      dataType = dataType.replace(/^ENUM\\(.+\\)/, this.pgEnumName(tableName, attr));\n    }\n\n    return dataType;\n  }\n\n  /**\n   * Generates an SQL query that returns all foreign keys of a table.\n   *\n   * @param  {string} tableName  The name of the table.\n   * @returns {string}            The generated sql query.\n   * @private\n   */\n  getForeignKeysQuery(tableName) {\n    return 'SELECT conname as constraint_name, pg_catalog.pg_get_constraintdef(r.oid, true) as condef FROM pg_catalog.pg_constraint r ' +\n      `WHERE r.conrelid = (SELECT oid FROM pg_class WHERE relname = '${tableName}' LIMIT 1) AND r.contype = 'f' ORDER BY 1;`;\n  }\n\n  /**\n   * Generate common SQL prefix for getForeignKeyReferencesQuery.\n   *\n   * @returns {string}\n   */\n  _getForeignKeyReferencesQueryPrefix() {\n    return 'SELECT ' +\n      'DISTINCT tc.constraint_name as constraint_name, ' +\n      'tc.constraint_schema as constraint_schema, ' +\n      'tc.constraint_catalog as constraint_catalog, ' +\n      'tc.table_name as table_name,' +\n      'tc.table_schema as table_schema,' +\n      'tc.table_catalog as table_catalog,' +\n      'tc.initially_deferred as initially_deferred,' +\n      'tc.is_deferrable as is_deferrable,' +\n      'kcu.column_name as column_name,' +\n      'ccu.table_schema  AS referenced_table_schema,' +\n      'ccu.table_catalog  AS referenced_table_catalog,' +\n      'ccu.table_name  AS referenced_table_name,' +\n      'ccu.column_name AS referenced_column_name ' +\n      'FROM information_schema.table_constraints AS tc ' +\n      'JOIN information_schema.key_column_usage AS kcu ' +\n      'ON tc.constraint_name = kcu.constraint_name ' +\n      'JOIN information_schema.constraint_column_usage AS ccu ' +\n      'ON ccu.constraint_name = tc.constraint_name ';\n  }\n\n  /**\n   * Generates an SQL query that returns all foreign keys details of a table.\n   *\n   * As for getForeignKeysQuery is not compatible with getForeignKeyReferencesQuery, so add a new function.\n   *\n   * @param {string} tableName\n   * @param {string} catalogName\n   * @param {string} schemaName\n   */\n  getForeignKeyReferencesQuery(tableName, catalogName, schemaName) {\n    return `${this._getForeignKeyReferencesQueryPrefix()\n    }WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name = '${tableName}'${\n      catalogName ? ` AND tc.table_catalog = '${catalogName}'` : ''\n    }${schemaName ? ` AND tc.table_schema = '${schemaName}'` : ''}`;\n  }\n\n  getForeignKeyReferenceQuery(table, columnName) {\n    const tableName = table.tableName || table;\n    const schema = table.schema;\n    return `${this._getForeignKeyReferencesQueryPrefix()\n    }WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name='${tableName}' AND  kcu.column_name = '${columnName}'${\n      schema ? ` AND tc.table_schema = '${schema}'` : ''}`;\n  }\n\n  /**\n   * Generates an SQL query that removes a foreign key from a table.\n   *\n   * @param  {string} tableName  The name of the table.\n   * @param  {string} foreignKey The name of the foreign key constraint.\n   * @returns {string}            The generated sql query.\n   * @private\n   */\n  dropForeignKeyQuery(tableName, foreignKey) {\n    return `ALTER TABLE ${this.quoteTable(tableName)} DROP CONSTRAINT ${this.quoteIdentifier(foreignKey)};`;\n  }\n\n  /**\n   * Quote identifier in sql clause\n   *\n   * @param {string} identifier\n   * @param {boolean} force\n   *\n   * @returns {string}\n   */\n  quoteIdentifier(identifier, force) {\n    const optForceQuote = force || false;\n    const optQuoteIdentifiers = this.options.quoteIdentifiers !== false;\n    const rawIdentifier = Utils.removeTicks(identifier, '\"');\n\n    if (\n      optForceQuote === true ||\n      optQuoteIdentifiers !== false ||\n      identifier.includes('.') ||\n      identifier.includes('->') ||\n      POSTGRES_RESERVED_WORDS.includes(rawIdentifier.toLowerCase())\n    ) {\n      // In Postgres if tables or attributes are created double-quoted,\n      // they are also case sensitive. If they contain any uppercase\n      // characters, they must always be double-quoted. This makes it\n      // impossible to write queries in portable SQL if tables are created in\n      // this way. Hence, we strip quotes if we don't want case sensitivity.\n      return Utils.addTicks(rawIdentifier, '\"');\n    }\n    return rawIdentifier;\n  }\n}\n\nmodule.exports = PostgresQueryGenerator;\n"],
  "mappings": "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",
  "names": []
}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists