node_modules ignore

This commit is contained in:
2025-05-08 23:43:47 +02:00
parent e19d52f172
commit 4574544c9f
65041 changed files with 10593536 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
/// <reference types="node" />
import type { Database } from '../..';
import Dialect from '../dialect';
import PostgresqlSchemaInspector from './schema-inspector';
export default class PostgresDialect extends Dialect {
schemaInspector: PostgresqlSchemaInspector;
constructor(db: Database);
useReturning(): boolean;
initialize(nativeConnection: unknown): Promise<void>;
usesForeignKeys(): boolean;
getSqlType(type: string): string;
transformErrors(error: NodeJS.ErrnoException): void;
}
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dialects/postgresql/index.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,OAAO,MAAM,YAAY,CAAC;AACjC,OAAO,yBAAyB,MAAM,oBAAoB,CAAC;AAE3D,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,OAAO;IAClD,eAAe,EAAE,yBAAyB,CAAC;gBAE/B,EAAE,EAAE,QAAQ;IAMxB,YAAY;IAIN,UAAU,CAAC,gBAAgB,EAAE,OAAO;IA+B1C,eAAe;IAIf,UAAU,CAAC,IAAI,EAAE,MAAM;IAWvB,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc;CAY7C"}

View File

@@ -0,0 +1,62 @@
'use strict';
var notNull = require('../../errors/not-null.js');
var dialect = require('../dialect.js');
var schemaInspector = require('./schema-inspector.js');
class PostgresDialect extends dialect {
useReturning() {
return true;
}
async initialize(nativeConnection) {
// Don't cast DATE string to Date()
this.db.connection.client.driver.types.setTypeParser(this.db.connection.client.driver.types.builtins.DATE, 'text', (v)=>v);
// Don't parse JSONB automatically
this.db.connection.client.driver.types.setTypeParser(this.db.connection.client.driver.types.builtins.JSONB, 'text', (v)=>v);
this.db.connection.client.driver.types.setTypeParser(this.db.connection.client.driver.types.builtins.NUMERIC, 'text', parseFloat);
// If we're using a schema, set the default path for all table names in queries to use that schema
// Ideally we would rely on Knex config.searchPath to do this for us
// However, createConnection must remain synchronous and if the user is using a connection function,
// we do not know what their schema is until after the connection is resolved
const schemaName = this.db.getSchemaName();
if (schemaName) {
await this.db.connection.raw(`SET search_path TO "${schemaName}"`).connection(nativeConnection);
}
}
usesForeignKeys() {
return true;
}
getSqlType(type) {
switch(type){
case 'timestamp':
{
return 'datetime';
}
default:
{
return type;
}
}
}
transformErrors(error) {
switch(error.code){
case '23502':
{
throw new notNull({
column: 'column' in error ? `${error.column}` : undefined
});
}
default:
{
super.transformErrors(error);
}
}
}
constructor(db){
super(db, 'postgres');
this.schemaInspector = new schemaInspector(db);
}
}
module.exports = PostgresDialect;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":["../../../src/dialects/postgresql/index.ts"],"sourcesContent":["import * as errors from '../../errors';\nimport type { Database } from '../..';\nimport Dialect from '../dialect';\nimport PostgresqlSchemaInspector from './schema-inspector';\n\nexport default class PostgresDialect extends Dialect {\n schemaInspector: PostgresqlSchemaInspector;\n\n constructor(db: Database) {\n super(db, 'postgres');\n\n this.schemaInspector = new PostgresqlSchemaInspector(db);\n }\n\n useReturning() {\n return true;\n }\n\n async initialize(nativeConnection: unknown) {\n // Don't cast DATE string to Date()\n this.db.connection.client.driver.types.setTypeParser(\n this.db.connection.client.driver.types.builtins.DATE,\n 'text',\n (v: unknown) => v\n );\n // Don't parse JSONB automatically\n this.db.connection.client.driver.types.setTypeParser(\n this.db.connection.client.driver.types.builtins.JSONB,\n 'text',\n (v: unknown) => v\n );\n this.db.connection.client.driver.types.setTypeParser(\n this.db.connection.client.driver.types.builtins.NUMERIC,\n 'text',\n parseFloat\n );\n\n // If we're using a schema, set the default path for all table names in queries to use that schema\n // Ideally we would rely on Knex config.searchPath to do this for us\n // However, createConnection must remain synchronous and if the user is using a connection function,\n // we do not know what their schema is until after the connection is resolved\n const schemaName = this.db.getSchemaName();\n if (schemaName) {\n await this.db.connection\n .raw(`SET search_path TO \"${schemaName}\"`)\n .connection(nativeConnection);\n }\n }\n\n usesForeignKeys() {\n return true;\n }\n\n getSqlType(type: string) {\n switch (type) {\n case 'timestamp': {\n return 'datetime';\n }\n default: {\n return type;\n }\n }\n }\n\n transformErrors(error: NodeJS.ErrnoException) {\n switch (error.code) {\n case '23502': {\n throw new errors.NotNullError({\n column: 'column' in error ? `${error.column}` : undefined,\n });\n }\n default: {\n super.transformErrors(error);\n }\n }\n }\n}\n"],"names":["PostgresDialect","Dialect","useReturning","initialize","nativeConnection","db","connection","client","driver","types","setTypeParser","builtins","DATE","v","JSONB","NUMERIC","parseFloat","schemaName","getSchemaName","raw","usesForeignKeys","getSqlType","type","transformErrors","error","code","errors","column","undefined","constructor","schemaInspector","PostgresqlSchemaInspector"],"mappings":";;;;;;AAKe,MAAMA,eAAwBC,SAAAA,OAAAA,CAAAA;IAS3CC,YAAe,GAAA;QACb,OAAO,IAAA;AACT;IAEA,MAAMC,UAAAA,CAAWC,gBAAyB,EAAE;;AAE1C,QAAA,IAAI,CAACC,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACC,aAAa,CAClD,IAAI,CAACL,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACE,QAAQ,CAACC,IAAI,EACpD,MAAA,EACA,CAACC,CAAeA,GAAAA,CAAAA,CAAAA;;AAGlB,QAAA,IAAI,CAACR,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACC,aAAa,CAClD,IAAI,CAACL,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACE,QAAQ,CAACG,KAAK,EACrD,MAAA,EACA,CAACD,CAAeA,GAAAA,CAAAA,CAAAA;AAElB,QAAA,IAAI,CAACR,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACC,aAAa,CAClD,IAAI,CAACL,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACE,QAAQ,CAACI,OAAO,EACvD,MACAC,EAAAA,UAAAA,CAAAA;;;;;AAOF,QAAA,MAAMC,UAAa,GAAA,IAAI,CAACZ,EAAE,CAACa,aAAa,EAAA;AACxC,QAAA,IAAID,UAAY,EAAA;AACd,YAAA,MAAM,IAAI,CAACZ,EAAE,CAACC,UAAU,CACrBa,GAAG,CAAC,CAAC,oBAAoB,EAAEF,UAAW,CAAA,CAAC,CAAC,CAAA,CACxCX,UAAU,CAACF,gBAAAA,CAAAA;AAChB;AACF;IAEAgB,eAAkB,GAAA;QAChB,OAAO,IAAA;AACT;AAEAC,IAAAA,UAAAA,CAAWC,IAAY,EAAE;QACvB,OAAQA,IAAAA;YACN,KAAK,WAAA;AAAa,gBAAA;oBAChB,OAAO,UAAA;AACT;AACA,YAAA;AAAS,gBAAA;oBACP,OAAOA,IAAAA;AACT;AACF;AACF;AAEAC,IAAAA,eAAAA,CAAgBC,KAA4B,EAAE;AAC5C,QAAA,OAAQA,MAAMC,IAAI;YAChB,KAAK,OAAA;AAAS,gBAAA;oBACZ,MAAM,IAAIC,OAAmB,CAAC;wBAC5BC,MAAQ,EAAA,QAAA,IAAYH,QAAQ,CAAC,EAAEA,MAAMG,MAAM,CAAC,CAAC,GAAGC;AAClD,qBAAA,CAAA;AACF;AACA,YAAA;AAAS,gBAAA;AACP,oBAAA,KAAK,CAACL,eAAgBC,CAAAA,KAAAA,CAAAA;AACxB;AACF;AACF;AAnEAK,IAAAA,WAAAA,CAAYxB,EAAY,CAAE;AACxB,QAAA,KAAK,CAACA,EAAI,EAAA,UAAA,CAAA;AAEV,QAAA,IAAI,CAACyB,eAAe,GAAG,IAAIC,eAA0B1B,CAAAA,EAAAA,CAAAA;AACvD;AAgEF;;;;"}

View File

@@ -0,0 +1,60 @@
import NotNullError from '../../errors/not-null.mjs';
import Dialect from '../dialect.mjs';
import PostgresqlSchemaInspector from './schema-inspector.mjs';
class PostgresDialect extends Dialect {
useReturning() {
return true;
}
async initialize(nativeConnection) {
// Don't cast DATE string to Date()
this.db.connection.client.driver.types.setTypeParser(this.db.connection.client.driver.types.builtins.DATE, 'text', (v)=>v);
// Don't parse JSONB automatically
this.db.connection.client.driver.types.setTypeParser(this.db.connection.client.driver.types.builtins.JSONB, 'text', (v)=>v);
this.db.connection.client.driver.types.setTypeParser(this.db.connection.client.driver.types.builtins.NUMERIC, 'text', parseFloat);
// If we're using a schema, set the default path for all table names in queries to use that schema
// Ideally we would rely on Knex config.searchPath to do this for us
// However, createConnection must remain synchronous and if the user is using a connection function,
// we do not know what their schema is until after the connection is resolved
const schemaName = this.db.getSchemaName();
if (schemaName) {
await this.db.connection.raw(`SET search_path TO "${schemaName}"`).connection(nativeConnection);
}
}
usesForeignKeys() {
return true;
}
getSqlType(type) {
switch(type){
case 'timestamp':
{
return 'datetime';
}
default:
{
return type;
}
}
}
transformErrors(error) {
switch(error.code){
case '23502':
{
throw new NotNullError({
column: 'column' in error ? `${error.column}` : undefined
});
}
default:
{
super.transformErrors(error);
}
}
}
constructor(db){
super(db, 'postgres');
this.schemaInspector = new PostgresqlSchemaInspector(db);
}
}
export { PostgresDialect as default };
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../src/dialects/postgresql/index.ts"],"sourcesContent":["import * as errors from '../../errors';\nimport type { Database } from '../..';\nimport Dialect from '../dialect';\nimport PostgresqlSchemaInspector from './schema-inspector';\n\nexport default class PostgresDialect extends Dialect {\n schemaInspector: PostgresqlSchemaInspector;\n\n constructor(db: Database) {\n super(db, 'postgres');\n\n this.schemaInspector = new PostgresqlSchemaInspector(db);\n }\n\n useReturning() {\n return true;\n }\n\n async initialize(nativeConnection: unknown) {\n // Don't cast DATE string to Date()\n this.db.connection.client.driver.types.setTypeParser(\n this.db.connection.client.driver.types.builtins.DATE,\n 'text',\n (v: unknown) => v\n );\n // Don't parse JSONB automatically\n this.db.connection.client.driver.types.setTypeParser(\n this.db.connection.client.driver.types.builtins.JSONB,\n 'text',\n (v: unknown) => v\n );\n this.db.connection.client.driver.types.setTypeParser(\n this.db.connection.client.driver.types.builtins.NUMERIC,\n 'text',\n parseFloat\n );\n\n // If we're using a schema, set the default path for all table names in queries to use that schema\n // Ideally we would rely on Knex config.searchPath to do this for us\n // However, createConnection must remain synchronous and if the user is using a connection function,\n // we do not know what their schema is until after the connection is resolved\n const schemaName = this.db.getSchemaName();\n if (schemaName) {\n await this.db.connection\n .raw(`SET search_path TO \"${schemaName}\"`)\n .connection(nativeConnection);\n }\n }\n\n usesForeignKeys() {\n return true;\n }\n\n getSqlType(type: string) {\n switch (type) {\n case 'timestamp': {\n return 'datetime';\n }\n default: {\n return type;\n }\n }\n }\n\n transformErrors(error: NodeJS.ErrnoException) {\n switch (error.code) {\n case '23502': {\n throw new errors.NotNullError({\n column: 'column' in error ? `${error.column}` : undefined,\n });\n }\n default: {\n super.transformErrors(error);\n }\n }\n }\n}\n"],"names":["PostgresDialect","Dialect","useReturning","initialize","nativeConnection","db","connection","client","driver","types","setTypeParser","builtins","DATE","v","JSONB","NUMERIC","parseFloat","schemaName","getSchemaName","raw","usesForeignKeys","getSqlType","type","transformErrors","error","code","errors","column","undefined","constructor","schemaInspector","PostgresqlSchemaInspector"],"mappings":";;;;AAKe,MAAMA,eAAwBC,SAAAA,OAAAA,CAAAA;IAS3CC,YAAe,GAAA;QACb,OAAO,IAAA;AACT;IAEA,MAAMC,UAAAA,CAAWC,gBAAyB,EAAE;;AAE1C,QAAA,IAAI,CAACC,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACC,aAAa,CAClD,IAAI,CAACL,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACE,QAAQ,CAACC,IAAI,EACpD,MAAA,EACA,CAACC,CAAeA,GAAAA,CAAAA,CAAAA;;AAGlB,QAAA,IAAI,CAACR,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACC,aAAa,CAClD,IAAI,CAACL,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACE,QAAQ,CAACG,KAAK,EACrD,MAAA,EACA,CAACD,CAAeA,GAAAA,CAAAA,CAAAA;AAElB,QAAA,IAAI,CAACR,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACC,aAAa,CAClD,IAAI,CAACL,EAAE,CAACC,UAAU,CAACC,MAAM,CAACC,MAAM,CAACC,KAAK,CAACE,QAAQ,CAACI,OAAO,EACvD,MACAC,EAAAA,UAAAA,CAAAA;;;;;AAOF,QAAA,MAAMC,UAAa,GAAA,IAAI,CAACZ,EAAE,CAACa,aAAa,EAAA;AACxC,QAAA,IAAID,UAAY,EAAA;AACd,YAAA,MAAM,IAAI,CAACZ,EAAE,CAACC,UAAU,CACrBa,GAAG,CAAC,CAAC,oBAAoB,EAAEF,UAAW,CAAA,CAAC,CAAC,CAAA,CACxCX,UAAU,CAACF,gBAAAA,CAAAA;AAChB;AACF;IAEAgB,eAAkB,GAAA;QAChB,OAAO,IAAA;AACT;AAEAC,IAAAA,UAAAA,CAAWC,IAAY,EAAE;QACvB,OAAQA,IAAAA;YACN,KAAK,WAAA;AAAa,gBAAA;oBAChB,OAAO,UAAA;AACT;AACA,YAAA;AAAS,gBAAA;oBACP,OAAOA,IAAAA;AACT;AACF;AACF;AAEAC,IAAAA,eAAAA,CAAgBC,KAA4B,EAAE;AAC5C,QAAA,OAAQA,MAAMC,IAAI;YAChB,KAAK,OAAA;AAAS,gBAAA;oBACZ,MAAM,IAAIC,YAAmB,CAAC;wBAC5BC,MAAQ,EAAA,QAAA,IAAYH,QAAQ,CAAC,EAAEA,MAAMG,MAAM,CAAC,CAAC,GAAGC;AAClD,qBAAA,CAAA;AACF;AACA,YAAA;AAAS,gBAAA;AACP,oBAAA,KAAK,CAACL,eAAgBC,CAAAA,KAAAA,CAAAA;AACxB;AACF;AACF;AAnEAK,IAAAA,WAAAA,CAAYxB,EAAY,CAAE;AACxB,QAAA,KAAK,CAACA,EAAI,EAAA,UAAA,CAAA;AAEV,QAAA,IAAI,CAACyB,eAAe,GAAG,IAAIC,yBAA0B1B,CAAAA,EAAAA,CAAAA;AACvD;AAgEF;;;;"}

View File

@@ -0,0 +1,14 @@
import type { Database } from '../..';
import type { Schema, Column, Index, ForeignKey } from '../../schema/types';
import type { SchemaInspector } from '../dialect';
export default class PostgresqlSchemaInspector implements SchemaInspector {
db: Database;
constructor(db: Database);
getSchema(): Promise<Schema>;
getDatabaseSchema(): string;
getTables(): Promise<string[]>;
getColumns(tableName: string): Promise<Column[]>;
getIndexes(tableName: string): Promise<Index[]>;
getForeignKeys(tableName: string): Promise<ForeignKey[]>;
}
//# sourceMappingURL=schema-inspector.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"schema-inspector.d.ts","sourceRoot":"","sources":["../../../src/dialects/postgresql/schema-inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA8JlD,MAAM,CAAC,OAAO,OAAO,yBAA0B,YAAW,eAAe;IACvE,EAAE,EAAE,QAAQ,CAAC;gBAED,EAAE,EAAE,QAAQ;IAIlB,SAAS;IAuBf,iBAAiB,IAAI,MAAM;IAIrB,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAQ9B,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAwBhD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IA2B/C,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAsD/D"}

View File

@@ -0,0 +1,316 @@
'use strict';
const SQL_QUERIES = {
TABLE_LIST: /* sql */ `
SELECT *
FROM information_schema.tables
WHERE
table_schema = ?
AND table_type = 'BASE TABLE'
AND table_name != 'geometry_columns'
AND table_name != 'spatial_ref_sys';
`,
LIST_COLUMNS: /* sql */ `
SELECT data_type, column_name, character_maximum_length, column_default, is_nullable
FROM information_schema.columns
WHERE table_schema = ? AND table_name = ?;
`,
INDEX_LIST: /* sql */ `
SELECT
ix.indexrelid,
i.relname as index_name,
a.attname as column_name,
ix.indisunique as is_unique,
ix.indisprimary as is_primary
FROM
pg_class t,
pg_namespace s,
pg_class i,
pg_index ix,
pg_attribute a
WHERE
t.oid = ix.indrelid
AND i.oid = ix.indexrelid
AND a.attrelid = t.oid
AND a.attnum = ANY(ix.indkey)
AND t.relkind = 'r'
AND t.relnamespace = s.oid
AND s.nspname = ?
AND t.relname = ?;
`,
FOREIGN_KEY_LIST: /* sql */ `
SELECT
tco."constraint_name" as constraint_name
FROM information_schema.table_constraints tco
WHERE
tco.constraint_type = 'FOREIGN KEY'
AND tco.constraint_schema = ?
AND tco.table_name = ?
`,
FOREIGN_KEY_REFERENCES: /* sql */ `
SELECT
kcu."constraint_name" as constraint_name,
kcu."column_name" as column_name
FROM information_schema.key_column_usage kcu
WHERE kcu.constraint_name=ANY(?)
AND kcu.table_schema = ?
AND kcu.table_name = ?;
`,
FOREIGN_KEY_REFERENCES_CONSTRAIN: /* sql */ `
SELECT
rco.update_rule as on_update,
rco.delete_rule as on_delete,
rco."unique_constraint_name" as unique_constraint_name
FROM information_schema.referential_constraints rco
WHERE rco.constraint_name=ANY(?)
AND rco.constraint_schema = ?
`,
FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE: /* sql */ `
SELECT
rel_kcu."table_name" as foreign_table,
rel_kcu."column_name" as fk_column_name
FROM information_schema.key_column_usage rel_kcu
WHERE rel_kcu.constraint_name=?
AND rel_kcu.table_schema = ?
`
};
const toStrapiType = (column)=>{
const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)?.[0];
switch(rootType){
case 'integer':
{
// find a way to figure out the increments
return {
type: 'integer'
};
}
case 'text':
{
return {
type: 'text',
args: [
'longtext'
]
};
}
case 'boolean':
{
return {
type: 'boolean'
};
}
case 'character':
{
return {
type: 'string',
args: [
column.character_maximum_length
]
};
}
case 'timestamp':
{
return {
type: 'datetime',
args: [
{
useTz: false,
precision: 6
}
]
};
}
case 'date':
{
return {
type: 'date'
};
}
case 'time':
{
return {
type: 'time',
args: [
{
precision: 3
}
]
};
}
case 'numeric':
{
return {
type: 'decimal',
args: [
10,
2
]
};
}
case 'real':
case 'double':
{
return {
type: 'double'
};
}
case 'bigint':
{
return {
type: 'bigInteger'
};
}
case 'jsonb':
{
return {
type: 'jsonb'
};
}
default:
{
return {
type: 'specificType',
args: [
column.data_type
]
};
}
}
};
const getIndexType = (index)=>{
if (index.is_primary) {
return 'primary';
}
if (index.is_unique) {
return 'unique';
}
};
class PostgresqlSchemaInspector {
async getSchema() {
const schema = {
tables: []
};
const tables = await this.getTables();
schema.tables = await Promise.all(tables.map(async (tableName)=>{
const columns = await this.getColumns(tableName);
const indexes = await this.getIndexes(tableName);
const foreignKeys = await this.getForeignKeys(tableName);
return {
name: tableName,
columns,
indexes,
foreignKeys
};
}));
return schema;
}
getDatabaseSchema() {
return this.db.getSchemaName() || 'public';
}
async getTables() {
const { rows } = await this.db.connection.raw(SQL_QUERIES.TABLE_LIST, [
this.getDatabaseSchema()
]);
return rows.map((row)=>row.table_name);
}
async getColumns(tableName) {
const { rows } = await this.db.connection.raw(SQL_QUERIES.LIST_COLUMNS, [
this.getDatabaseSchema(),
tableName
]);
return rows.map((row)=>{
const { type, args = [], ...rest } = toStrapiType(row);
const defaultTo = row.column_default && row.column_default.includes('nextval(') ? null : row.column_default;
return {
type,
args,
defaultTo,
name: row.column_name,
notNullable: row.is_nullable === 'NO',
unsigned: false,
...rest
};
});
}
async getIndexes(tableName) {
const { rows } = await this.db.connection.raw(SQL_QUERIES.INDEX_LIST, [
this.getDatabaseSchema(),
tableName
]);
const ret = {};
for (const index of rows){
if (index.column_name === 'id') {
continue;
}
if (!ret[index.indexrelid]) {
ret[index.indexrelid] = {
columns: [
index.column_name
],
name: index.index_name,
type: getIndexType(index)
};
} else {
ret[index.indexrelid].columns.push(index.column_name);
}
}
return Object.values(ret);
}
async getForeignKeys(tableName) {
const { rows } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_LIST, [
this.getDatabaseSchema(),
tableName
]);
const ret = {};
for (const fk of rows){
ret[fk.constraint_name] = {
name: fk.constraint_name,
columns: [],
referencedColumns: [],
referencedTable: null,
onUpdate: null,
onDelete: null
};
}
const constraintNames = Object.keys(ret);
const dbSchema = this.getDatabaseSchema();
if (constraintNames.length > 0) {
const { rows: fkReferences } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES, [
[
constraintNames
],
dbSchema,
tableName
]);
for (const fkReference of fkReferences){
ret[fkReference.constraint_name].columns.push(fkReference.column_name);
const { rows: fkReferencesConstraint } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN, [
[
fkReference.constraint_name
],
dbSchema
]);
for (const fkReferenceC of fkReferencesConstraint){
const { rows: fkReferencesConstraintReferece } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE, [
fkReferenceC.unique_constraint_name,
dbSchema
]);
for (const fkReferenceConst of fkReferencesConstraintReferece){
ret[fkReference.constraint_name].referencedTable = fkReferenceConst.foreign_table;
ret[fkReference.constraint_name].referencedColumns.push(fkReferenceConst.fk_column_name);
}
ret[fkReference.constraint_name].onUpdate = fkReferenceC.on_update.toUpperCase();
ret[fkReference.constraint_name].onDelete = fkReferenceC.on_delete.toUpperCase();
}
}
}
return Object.values(ret);
}
constructor(db){
this.db = db;
}
}
module.exports = PostgresqlSchemaInspector;
//# sourceMappingURL=schema-inspector.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,314 @@
const SQL_QUERIES = {
TABLE_LIST: /* sql */ `
SELECT *
FROM information_schema.tables
WHERE
table_schema = ?
AND table_type = 'BASE TABLE'
AND table_name != 'geometry_columns'
AND table_name != 'spatial_ref_sys';
`,
LIST_COLUMNS: /* sql */ `
SELECT data_type, column_name, character_maximum_length, column_default, is_nullable
FROM information_schema.columns
WHERE table_schema = ? AND table_name = ?;
`,
INDEX_LIST: /* sql */ `
SELECT
ix.indexrelid,
i.relname as index_name,
a.attname as column_name,
ix.indisunique as is_unique,
ix.indisprimary as is_primary
FROM
pg_class t,
pg_namespace s,
pg_class i,
pg_index ix,
pg_attribute a
WHERE
t.oid = ix.indrelid
AND i.oid = ix.indexrelid
AND a.attrelid = t.oid
AND a.attnum = ANY(ix.indkey)
AND t.relkind = 'r'
AND t.relnamespace = s.oid
AND s.nspname = ?
AND t.relname = ?;
`,
FOREIGN_KEY_LIST: /* sql */ `
SELECT
tco."constraint_name" as constraint_name
FROM information_schema.table_constraints tco
WHERE
tco.constraint_type = 'FOREIGN KEY'
AND tco.constraint_schema = ?
AND tco.table_name = ?
`,
FOREIGN_KEY_REFERENCES: /* sql */ `
SELECT
kcu."constraint_name" as constraint_name,
kcu."column_name" as column_name
FROM information_schema.key_column_usage kcu
WHERE kcu.constraint_name=ANY(?)
AND kcu.table_schema = ?
AND kcu.table_name = ?;
`,
FOREIGN_KEY_REFERENCES_CONSTRAIN: /* sql */ `
SELECT
rco.update_rule as on_update,
rco.delete_rule as on_delete,
rco."unique_constraint_name" as unique_constraint_name
FROM information_schema.referential_constraints rco
WHERE rco.constraint_name=ANY(?)
AND rco.constraint_schema = ?
`,
FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE: /* sql */ `
SELECT
rel_kcu."table_name" as foreign_table,
rel_kcu."column_name" as fk_column_name
FROM information_schema.key_column_usage rel_kcu
WHERE rel_kcu.constraint_name=?
AND rel_kcu.table_schema = ?
`
};
const toStrapiType = (column)=>{
const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)?.[0];
switch(rootType){
case 'integer':
{
// find a way to figure out the increments
return {
type: 'integer'
};
}
case 'text':
{
return {
type: 'text',
args: [
'longtext'
]
};
}
case 'boolean':
{
return {
type: 'boolean'
};
}
case 'character':
{
return {
type: 'string',
args: [
column.character_maximum_length
]
};
}
case 'timestamp':
{
return {
type: 'datetime',
args: [
{
useTz: false,
precision: 6
}
]
};
}
case 'date':
{
return {
type: 'date'
};
}
case 'time':
{
return {
type: 'time',
args: [
{
precision: 3
}
]
};
}
case 'numeric':
{
return {
type: 'decimal',
args: [
10,
2
]
};
}
case 'real':
case 'double':
{
return {
type: 'double'
};
}
case 'bigint':
{
return {
type: 'bigInteger'
};
}
case 'jsonb':
{
return {
type: 'jsonb'
};
}
default:
{
return {
type: 'specificType',
args: [
column.data_type
]
};
}
}
};
const getIndexType = (index)=>{
if (index.is_primary) {
return 'primary';
}
if (index.is_unique) {
return 'unique';
}
};
class PostgresqlSchemaInspector {
async getSchema() {
const schema = {
tables: []
};
const tables = await this.getTables();
schema.tables = await Promise.all(tables.map(async (tableName)=>{
const columns = await this.getColumns(tableName);
const indexes = await this.getIndexes(tableName);
const foreignKeys = await this.getForeignKeys(tableName);
return {
name: tableName,
columns,
indexes,
foreignKeys
};
}));
return schema;
}
getDatabaseSchema() {
return this.db.getSchemaName() || 'public';
}
async getTables() {
const { rows } = await this.db.connection.raw(SQL_QUERIES.TABLE_LIST, [
this.getDatabaseSchema()
]);
return rows.map((row)=>row.table_name);
}
async getColumns(tableName) {
const { rows } = await this.db.connection.raw(SQL_QUERIES.LIST_COLUMNS, [
this.getDatabaseSchema(),
tableName
]);
return rows.map((row)=>{
const { type, args = [], ...rest } = toStrapiType(row);
const defaultTo = row.column_default && row.column_default.includes('nextval(') ? null : row.column_default;
return {
type,
args,
defaultTo,
name: row.column_name,
notNullable: row.is_nullable === 'NO',
unsigned: false,
...rest
};
});
}
async getIndexes(tableName) {
const { rows } = await this.db.connection.raw(SQL_QUERIES.INDEX_LIST, [
this.getDatabaseSchema(),
tableName
]);
const ret = {};
for (const index of rows){
if (index.column_name === 'id') {
continue;
}
if (!ret[index.indexrelid]) {
ret[index.indexrelid] = {
columns: [
index.column_name
],
name: index.index_name,
type: getIndexType(index)
};
} else {
ret[index.indexrelid].columns.push(index.column_name);
}
}
return Object.values(ret);
}
async getForeignKeys(tableName) {
const { rows } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_LIST, [
this.getDatabaseSchema(),
tableName
]);
const ret = {};
for (const fk of rows){
ret[fk.constraint_name] = {
name: fk.constraint_name,
columns: [],
referencedColumns: [],
referencedTable: null,
onUpdate: null,
onDelete: null
};
}
const constraintNames = Object.keys(ret);
const dbSchema = this.getDatabaseSchema();
if (constraintNames.length > 0) {
const { rows: fkReferences } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES, [
[
constraintNames
],
dbSchema,
tableName
]);
for (const fkReference of fkReferences){
ret[fkReference.constraint_name].columns.push(fkReference.column_name);
const { rows: fkReferencesConstraint } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN, [
[
fkReference.constraint_name
],
dbSchema
]);
for (const fkReferenceC of fkReferencesConstraint){
const { rows: fkReferencesConstraintReferece } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE, [
fkReferenceC.unique_constraint_name,
dbSchema
]);
for (const fkReferenceConst of fkReferencesConstraintReferece){
ret[fkReference.constraint_name].referencedTable = fkReferenceConst.foreign_table;
ret[fkReference.constraint_name].referencedColumns.push(fkReferenceConst.fk_column_name);
}
ret[fkReference.constraint_name].onUpdate = fkReferenceC.on_update.toUpperCase();
ret[fkReference.constraint_name].onDelete = fkReferenceC.on_delete.toUpperCase();
}
}
}
return Object.values(ret);
}
constructor(db){
this.db = db;
}
}
export { PostgresqlSchemaInspector as default };
//# sourceMappingURL=schema-inspector.mjs.map

File diff suppressed because one or more lines are too long