forked from tsai/budibase
8 changed files with 255 additions and 143 deletions
@ -1,135 +1,135 @@ |
|||||
const Sql = require("../base/sql") |
// const Sql = require("../base/sql")
|
||||
const { Pool } = require("pg") |
// const { Pool } = require("pg")
|
||||
const { FieldTypes } = require("../../constants") |
// const { FieldTypes } = require("../../constants")
|
||||
const { FIELD_TYPES } = require("../Integration") |
// const { FIELD_TYPES } = require("../Integration")
|
||||
const { SEPARATOR } = require("@budibase/auth/db") |
// const { SEPARATOR } = require("@budibase/auth/db")
|
||||
|
|
||||
const TYPE_MAP = { |
// const TYPE_MAP = {
|
||||
text: FieldTypes.LONGFORM, |
// text: FieldTypes.LONGFORM,
|
||||
varchar: FieldTypes.STRING, |
// varchar: FieldTypes.STRING,
|
||||
integer: FieldTypes.NUMBER, |
// integer: FieldTypes.NUMBER,
|
||||
bigint: FieldTypes.NUMBER, |
// bigint: FieldTypes.NUMBER,
|
||||
decimal: FieldTypes.NUMBER, |
// decimal: FieldTypes.NUMBER,
|
||||
smallint: FieldTypes.NUMBER, |
// smallint: FieldTypes.NUMBER,
|
||||
timestamp: FieldTypes.DATETIME, |
// timestamp: FieldTypes.DATETIME,
|
||||
time: FieldTypes.DATETIME, |
// time: FieldTypes.DATETIME,
|
||||
boolean: FieldTypes.BOOLEAN, |
// boolean: FieldTypes.BOOLEAN,
|
||||
json: FIELD_TYPES.JSON, |
// json: FIELD_TYPES.JSON,
|
||||
} |
// }
|
||||
|
|
||||
const SCHEMA = { |
// const SCHEMA = {
|
||||
friendlyName: "PostgreSQL", |
// friendlyName: "PostgreSQL",
|
||||
description: |
// description:
|
||||
"PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.", |
// "PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.",
|
||||
plus: true, |
// plus: true,
|
||||
datasource: { |
// datasource: {
|
||||
host: { |
// host: {
|
||||
type: FIELD_TYPES.STRING, |
// type: FIELD_TYPES.STRING,
|
||||
default: "localhost", |
// default: "localhost",
|
||||
required: true, |
// required: true,
|
||||
}, |
// },
|
||||
port: { |
// port: {
|
||||
type: FIELD_TYPES.NUMBER, |
// type: FIELD_TYPES.NUMBER,
|
||||
required: true, |
// required: true,
|
||||
default: 5432, |
// default: 5432,
|
||||
}, |
// },
|
||||
database: { |
// database: {
|
||||
type: FIELD_TYPES.STRING, |
// type: FIELD_TYPES.STRING,
|
||||
default: "postgres", |
// default: "postgres",
|
||||
required: true, |
// required: true,
|
||||
}, |
// },
|
||||
user: { |
// user: {
|
||||
type: FIELD_TYPES.STRING, |
// type: FIELD_TYPES.STRING,
|
||||
default: "root", |
// default: "root",
|
||||
required: true, |
// required: true,
|
||||
}, |
// },
|
||||
password: { |
// password: {
|
||||
type: FIELD_TYPES.PASSWORD, |
// type: FIELD_TYPES.PASSWORD,
|
||||
default: "root", |
// default: "root",
|
||||
required: true, |
// required: true,
|
||||
}, |
// },
|
||||
ssl: { |
// ssl: {
|
||||
type: FIELD_TYPES.BOOLEAN, |
// type: FIELD_TYPES.BOOLEAN,
|
||||
default: false, |
// default: false,
|
||||
required: false, |
// required: false,
|
||||
}, |
// },
|
||||
}, |
// },
|
||||
} |
// }
|
||||
|
|
||||
class PostgresPlus extends Sql { |
// class PostgresPlus extends Sql {
|
||||
static pool |
// static pool
|
||||
COLUMNS_SQL = |
// COLUMNS_SQL =
|
||||
"select * from information_schema.columns where table_schema = 'public'" |
// "select * from information_schema.columns where table_schema = 'public'"
|
||||
|
|
||||
PRIMARY_KEYS_SQL = ` |
// PRIMARY_KEYS_SQL = `
|
||||
select tc.table_schema, tc.table_name, kc.column_name as primary_key |
// select tc.table_schema, tc.table_name, kc.column_name as primary_key
|
||||
from information_schema.table_constraints tc |
// from information_schema.table_constraints tc
|
||||
join |
// join
|
||||
information_schema.key_column_usage kc on kc.table_name = tc.table_name |
// information_schema.key_column_usage kc on kc.table_name = tc.table_name
|
||||
and kc.table_schema = tc.table_schema |
// and kc.table_schema = tc.table_schema
|
||||
and kc.constraint_name = tc.constraint_name |
// and kc.constraint_name = tc.constraint_name
|
||||
where tc.constraint_type = 'PRIMARY KEY'; |
// where tc.constraint_type = 'PRIMARY KEY';
|
||||
` |
// `
|
||||
|
|
||||
constructor(config, datasource) { |
// constructor(config, datasource) {
|
||||
super("pg") |
// super("pg")
|
||||
this.config = config |
// this.config = config
|
||||
this.datasource = datasource |
// this.datasource = datasource
|
||||
|
|
||||
if (!this.pool) { |
// if (!this.pool) {
|
||||
this.pool = new Pool(this.config) |
// this.pool = new Pool(this.config)
|
||||
} |
// }
|
||||
|
|
||||
this.client = this.pool |
// this.client = this.pool
|
||||
} |
// }
|
||||
|
|
||||
async init(datasourceId) { |
// async init(datasourceId) {
|
||||
let keys = [] |
// let keys = []
|
||||
try { |
// try {
|
||||
const primaryKeysResponse = await this.client.query(this.PRIMARY_KEYS_SQL) |
// const primaryKeysResponse = await this.client.query(this.PRIMARY_KEYS_SQL)
|
||||
for (let table of primaryKeysResponse.rows) { |
// for (let table of primaryKeysResponse.rows) {
|
||||
keys.push(table.column_name || table.primary_key) |
// keys.push(table.column_name || table.primary_key)
|
||||
} |
// }
|
||||
} catch (err) { |
// } catch (err) {
|
||||
// TODO: this try catch method isn't right
|
// // TODO: this try catch method isn't right
|
||||
keys = ["id"] |
// keys = ["id"]
|
||||
} |
// }
|
||||
|
|
||||
const columnsResponse = await this.client.query(this.COLUMNS_SQL) |
// const columnsResponse = await this.client.query(this.COLUMNS_SQL)
|
||||
const tables = {} |
// const tables = {}
|
||||
|
|
||||
for (let column of columnsResponse.rows) { |
// for (let column of columnsResponse.rows) {
|
||||
const tableName = column.table_name |
// const tableName = column.table_name
|
||||
const columnName = column.column_name |
// const columnName = column.column_name
|
||||
|
|
||||
// table key doesn't exist yet
|
// // table key doesn't exist yet
|
||||
if (!tables[tableName]) { |
// if (!tables[tableName]) {
|
||||
tables[tableName] = { |
// tables[tableName] = {
|
||||
_id: `${datasourceId}${SEPARATOR}${tableName}`, |
// _id: `${datasourceId}${SEPARATOR}${tableName}`,
|
||||
// TODO: this needs to accommodate composite keys
|
// // TODO: this needs to accommodate composite keys
|
||||
primary: keys, |
// primary: keys,
|
||||
name: tableName, |
// name: tableName,
|
||||
schema: {}, |
// schema: {},
|
||||
} |
// }
|
||||
} |
// }
|
||||
|
|
||||
tables[tableName].schema[columnName] = { |
// tables[tableName].schema[columnName] = {
|
||||
name: columnName, |
// name: columnName,
|
||||
type: TYPE_MAP[column.data_type] || FIELD_TYPES.STRING, |
// type: TYPE_MAP[column.data_type] || FIELD_TYPES.STRING,
|
||||
} |
// }
|
||||
} |
// }
|
||||
this.tables = tables |
// this.tables = tables
|
||||
} |
// }
|
||||
|
|
||||
async query(json) { |
// async query(json) {
|
||||
const operation = this._operation(json).toLowerCase() |
// const operation = this._operation(json).toLowerCase()
|
||||
const sql = this._query(json) |
// const sql = this._query(json)
|
||||
const response = await this.client.query(sql.sql, sql.bindings) |
// const response = await this.client.query(sql.sql, sql.bindings)
|
||||
return response.rows.length ? response.rows : [{ [operation]: true }] |
// return response.rows.length ? response.rows : [{ [operation]: true }]
|
||||
} |
// }
|
||||
} |
// }
|
||||
|
|
||||
module.exports = { |
// module.exports = {
|
||||
schema: SCHEMA, |
// schema: SCHEMA,
|
||||
integration: PostgresPlus, |
// integration: PostgresPlus,
|
||||
} |
// }
|
||||
|
|||||
Loading…
Reference in new issue