From 87812564c22db89a5e2655e93b6ea241156ea477 Mon Sep 17 00:00:00 2001 From: Junaid Ahmed Date: Thu, 30 Mar 2023 11:11:38 -0400 Subject: [PATCH 01/10] added pool creations for both rds mqsl and rds pg databases. still needs to be fleshed out into different functions and different RDS_CREDS, hence not pushed to dev yet --- backend/models.ts | 56 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/backend/models.ts b/backend/models.ts index 4e3b8df0..c194dc04 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -28,6 +28,8 @@ const docConfig = require('./_documentsConfig'); let pg_pool; let msql_pool; +let rds_pg_pool; +let rds_msql_pool; // *********************************************************** HELPER FUNCTIONS ************************************************* // @@ -36,14 +38,12 @@ let msql_pool; const getColumnObjects = function ( tableName: string, dbType: DBType // error? - ): Promise { - let queryString; - - const value = [tableName]; +): Promise { + let queryString; - + const value = [tableName]; - if (dbType === DBType.Postgres) { + if (dbType === DBType.Postgres) { // query string to get constraints and table references as well queryString = `SELECT DISTINCT cols.column_name, cols.data_type, @@ -65,9 +65,9 @@ const getColumnObjects = function ( ON rco.unique_constraint_name = rel_kcu.constraint_name WHERE cols.table_name = $1`; - //kcu = key column usage = describes which key columns have constraints - //tc = table constraints = shows if constraint is primary key or foreign key - //information_schema.table_constraints show the whole table constraints + //kcu = key column usage = describes which key columns have constraints + //tc = table constraints = shows if constraint is primary key or foreign key + //information_schema.table_constraints show the whole table constraints return new Promise((resolve, reject) => { pg_pool @@ -227,7 +227,6 @@ const getDBLists = function ( const promiseArray: Promise[] = []; // console.log('dbType - getDBLists: ', dbType); - if (dbType === DBType.Postgres) { query = `SELECT @@ -362,6 +361,43 @@ const myObj: MyObj = { async setBaseConnections() { const PG_Cred = docConfig.getCredentials(DBType.Postgres); const MSQL_Cred = docConfig.getCredentials(DBType.MySQL); + //JUNAID + //destructuring rds creds from docConfig.getFullConfig. Doing it this way for now so that i dont have to go back and change the types for the docConfig and create another method to send just the RDS Credentials. can refactor later. + const { rds_host, rds_user, rds_pass, rds_port } = + docConfig.getFullConfig(); + const RDS_Creds = { + host: rds_host, + user: rds_user, + password: rds_pass, + port: rds_port, + }; + + //JUNAID + //one is commented out rn bc we can only connect to one cloud db at a time since we only have one text field for the cloud. also we need to add new vars and types for the second cloud connection. both cloud connections can use the same format as the current RDS_CREDS var + + //rds pg pool conn + if (rds_pg_pool) { + await rds_pg_pool.end(); + } + // rds_pg_pool = new Pool({ ...RDS_Creds }); + // console.log(RDS_Creds); + // rds_pg_pool.connect((err) => { + // if (err) { + // console.log(err, 'ERR PG'); + // } else { + // console.log('connected to db'); + // } + // }); + + //rds msql pool conn + if (rds_msql_pool) { + await rds_msql_pool.end(); + } + rds_msql_pool = mysql.createPool({ ...RDS_Creds }); + + //just a test query to make sure were connected (it works, i tested with other queries creating tables too) + const q = await rds_msql_pool.query('SHOW DATABASES;'); + console.log(q, 'q'); // URI Format: postgres://username:password@hostname:port/databasename // Note User must have a 'postgres'role set-up prior to initializing this connection. https://www.postgresql.org/docs/13/database-roles.html From 777c20e50982fad85b29eb4f1f4be6c322b20867 Mon Sep 17 00:00:00 2001 From: Junaid Ahmed Date: Thu, 30 Mar 2023 14:06:03 -0400 Subject: [PATCH 02/10] adding pg and msql rds --- backend/BE_types.ts | 12 +- backend/_documentsConfig.ts | 12 +- backend/models.ts | 52 +++++--- frontend/components/Dialog/ConfigView.tsx | 142 +++++++++++++++++----- 4 files changed, 161 insertions(+), 57 deletions(-) diff --git a/backend/BE_types.ts b/backend/BE_types.ts index 12cb0828..4beeb258 100644 --- a/backend/BE_types.ts +++ b/backend/BE_types.ts @@ -58,8 +58,12 @@ export interface DocConfigFile { pg_user: string; pg_pass: string; pg_port: number | string; - rds_host: string; - rds_user: string; - rds_pass: string; - rds_port: string | number; + rds_mysql_host: string; + rds_mysql_user: string; + rds_mysql_pass: string; + rds_mysql_port: string | number; + rds_pg_host: string; + rds_pg_user: string; + rds_pg_pass: string; + rds_pg_port: string | number; } diff --git a/backend/_documentsConfig.ts b/backend/_documentsConfig.ts index 0562e263..3e30f905 100644 --- a/backend/_documentsConfig.ts +++ b/backend/_documentsConfig.ts @@ -21,10 +21,14 @@ const writeConfigDefault = function (): DocConfigFile { pg_user: 'postgres', pg_pass: 'postgres', pg_port: 5432, - rds_host: 'AWS RDS', - rds_user: 'RDS', - rds_pass: 'password', - rds_port: 'Port', + rds_mysql_host: 'AWS RDS', + rds_mysql_user: 'RDS', + rds_mysql_pass: 'password', + rds_mysql_port: 3306, + rds_pg_host: 'AWS RDS', + rds_pg_user: 'RDS', + rds_pg_pass: 'password', + rds_pg_port: 5432, }; fs.writeFileSync(configPath, JSON.stringify(defaultFile)); diff --git a/backend/models.ts b/backend/models.ts index c194dc04..8ede0b8a 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -363,15 +363,28 @@ const myObj: MyObj = { const MSQL_Cred = docConfig.getCredentials(DBType.MySQL); //JUNAID //destructuring rds creds from docConfig.getFullConfig. Doing it this way for now so that i dont have to go back and change the types for the docConfig and create another method to send just the RDS Credentials. can refactor later. - const { rds_host, rds_user, rds_pass, rds_port } = - docConfig.getFullConfig(); - const RDS_Creds = { - host: rds_host, - user: rds_user, - password: rds_pass, - port: rds_port, + const { + rds_mysql_host, + rds_mysql_user, + rds_mysql_pass, + rds_mysql_port, + rds_pg_host, + rds_pg_user, + rds_pg_pass, + rds_pg_port, + } = docConfig.getFullConfig(); + const RDS_MySQL_Creds = { + host: rds_mysql_host, + user: rds_mysql_user, + password: rds_mysql_pass, + port: rds_mysql_port, + }; + const RDS_PG_Creds = { + host: rds_pg_host, + user: rds_pg_user, + password: rds_pg_pass, + port: rds_pg_port, }; - //JUNAID //one is commented out rn bc we can only connect to one cloud db at a time since we only have one text field for the cloud. also we need to add new vars and types for the second cloud connection. both cloud connections can use the same format as the current RDS_CREDS var @@ -379,25 +392,26 @@ const myObj: MyObj = { if (rds_pg_pool) { await rds_pg_pool.end(); } - // rds_pg_pool = new Pool({ ...RDS_Creds }); - // console.log(RDS_Creds); - // rds_pg_pool.connect((err) => { - // if (err) { - // console.log(err, 'ERR PG'); - // } else { - // console.log('connected to db'); - // } - // }); + rds_pg_pool = new Pool(RDS_PG_Creds); + rds_pg_pool.connect((err) => { + if (err) { + console.log(err, 'ERR PG'); + } else { + console.log('connected to pg db'); + } + }); //rds msql pool conn if (rds_msql_pool) { await rds_msql_pool.end(); } - rds_msql_pool = mysql.createPool({ ...RDS_Creds }); + rds_msql_pool = mysql.createPool(RDS_MySQL_Creds); //just a test query to make sure were connected (it works, i tested with other queries creating tables too) const q = await rds_msql_pool.query('SHOW DATABASES;'); - console.log(q, 'q'); + console.log('-----mysqlrds query testing conn-------'); + console.log(q[0]); + console.log('-----mysqlrds query testing conn-------'); // URI Format: postgres://username:password@hostname:port/databasename // Note User must have a 'postgres'role set-up prior to initializing this connection. https://www.postgresql.org/docs/13/database-roles.html diff --git a/frontend/components/Dialog/ConfigView.tsx b/frontend/components/Dialog/ConfigView.tsx index feda52d1..61b1f86a 100644 --- a/frontend/components/Dialog/ConfigView.tsx +++ b/frontend/components/Dialog/ConfigView.tsx @@ -51,17 +51,21 @@ const ConfigView = ({ show, onClose }: ConfigViewProps) => { const [pg_user, setPG_User] = useState(''); const [pg_pass, setPG_Pass] = useState(''); const [pg_port, setPG_Port] = useState(''); - const [rds_user, setRDS_User] = useState(''); - const [rds_pass, setRDS_Pass] = useState(''); - const [rds_host, setRDS_Host] = useState(''); - const [rds_port, setRDS_Port] = useState(''); + const [rds_mysql_user, setRDS_MySQL_User] = useState(''); + const [rds_mysql_pass, setRDS_MySQL_Pass] = useState(''); + const [rds_mysql_host, setRDS_MySQL_Host] = useState(''); + const [rds_mysql_port, setRDS_MySQL_Port] = useState(''); + const [rds_pg_user, setRDS_PG_User] = useState(''); + const [rds_pg_pass, setRDS_PG_Pass] = useState(''); + const [rds_pg_host, setRDS_PG_Host] = useState(''); + const [rds_pg_port, setRDS_PG_Port] = useState(''); const [mysql_showpass, setMySQL_ShowPass] = useState(false); const [pg_showpass, setPG_ShowPass] = useState(false); - const [rds_showpass, setRDS_ShowPass] = useState(false); + const [rds_mysql_showpass, setRDS_MySQL_ShowPass] = useState(false); + const [rds_pg_showpass, setRDS_PG_ShowPass] = useState(false); useEffect(() => { - console.log(rds_port) // Listen to backend for updates to list of available databases const configFromBackend = (evt: IpcRendererEvent, config) => { setMySQL_User(config.mysql_user); @@ -70,10 +74,14 @@ const ConfigView = ({ show, onClose }: ConfigViewProps) => { setPG_User(config.pg_user); setPG_Pass(config.pg_pass); setPG_Port(config.pg_port); - setRDS_User(config.rds_user); - setRDS_Pass(config.rds_pass); - setRDS_Host(config.rds_host); - setRDS_Port(config.rds_port); + setRDS_MySQL_User(config.rds_mysql_user); + setRDS_MySQL_Pass(config.rds_mysql_pass); + setRDS_MySQL_Host(config.rds_mysql_host); + setRDS_MySQL_Port(config.rds_mysql_port); + setRDS_PG_User(config.rds_pg_user); + setRDS_PG_Pass(config.rds_pg_pass); + setRDS_PG_Host(config.rds_pg_host); + setRDS_PG_Port(config.rds_pg_port); }; ipcRenderer.on('get-config', configFromBackend); requestConfig(); @@ -97,10 +105,14 @@ const ConfigView = ({ show, onClose }: ConfigViewProps) => { pg_user, pg_pass, pg_port: parseInt(pg_port), - rds_user, - rds_pass, - rds_host, - rds_port: parseInt(rds_port), + rds_mysql_user, + rds_mysql_pass, + rds_mysql_host, + rds_mysql_port: parseInt(rds_mysql_port), + rds_pg_user, + rds_pg_pass, + rds_pg_host, + rds_pg_port: parseInt(rds_pg_port), }) .then(() => { handleClose(); @@ -242,26 +254,26 @@ const ConfigView = ({ show, onClose }: ConfigViewProps) => { { - setRDS_User(event.target.value); + setRDS_MySQL_User(event.target.value); }} InputProps={{ style: { color: '#575151' }, }} - defaultValue={rds_user} + defaultValue={rds_mysql_user} /> { - setRDS_Pass(event.target.value); + setRDS_MySQL_Pass(event.target.value); }} InputProps={{ style: { color: '#575151' }, @@ -269,43 +281,113 @@ const ConfigView = ({ show, onClose }: ConfigViewProps) => { setRDS_ShowPass(!rds_showpass)} - onMouseDown={() => setRDS_ShowPass(!rds_showpass)} + onClick={() => setRDS_MySQL_ShowPass(!rds_mysql_showpass)} + onMouseDown={() => + setRDS_MySQL_ShowPass(!rds_mysql_showpass) + } > - {rds_showpass ? : } + {rds_mysql_showpass ? : } ), }} - defaultValue={rds_pass} + defaultValue={rds_mysql_pass} /> { - setRDS_Host(event.target.value); + setRDS_MySQL_Host(event.target.value); }} InputProps={{ style: { color: '#575151' }, }} - defaultValue={rds_host} + defaultValue={rds_mysql_host} /> { - setRDS_Port(event.target.value); + setRDS_MySQL_Port(event.target.value); }} InputProps={{ style: { color: '#575151' }, }} - defaultValue={rds_port} + defaultValue={rds_mysql_port} + /> + { + setRDS_PG_User(event.target.value); + }} + InputProps={{ + style: { color: '#575151' }, + }} + defaultValue={rds_pg_user} + /> + { + setRDS_PG_Pass(event.target.value); + }} + InputProps={{ + style: { color: '#575151' }, + endAdornment: ( + + setRDS_PG_ShowPass(!rds_pg_showpass)} + onMouseDown={() => setRDS_PG_ShowPass(!rds_pg_showpass)} + > + {rds_pg_showpass ? : } + + + ), + }} + defaultValue={rds_pg_pass} + /> + { + setRDS_PG_Host(event.target.value); + }} + InputProps={{ + style: { color: '#575151' }, + }} + defaultValue={rds_pg_host} + /> + { + setRDS_PG_Port(event.target.value); + }} + InputProps={{ + style: { color: '#575151' }, + }} + defaultValue={rds_pg_port} /> From 4fc67125bfa9c2fbac23f2a23268d930f80283ea Mon Sep 17 00:00:00 2001 From: Junaid Ahmed Date: Thu, 30 Mar 2023 16:48:34 -0400 Subject: [PATCH 03/10] four concurrent connections done, 2 rds and 2 local --- backend/models.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/models.ts b/backend/models.ts index 8ede0b8a..f4e92da7 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -392,6 +392,7 @@ const myObj: MyObj = { if (rds_pg_pool) { await rds_pg_pool.end(); } + console.log(RDS_PG_Creds) rds_pg_pool = new Pool(RDS_PG_Creds); rds_pg_pool.connect((err) => { if (err) { From 0f74290d8fc94d4e99725ee7df912090e49cf452 Mon Sep 17 00:00:00 2001 From: ChaseSizemore Date: Thu, 30 Mar 2023 16:49:14 -0400 Subject: [PATCH 04/10] edited models and docconfig and betype --- backend/BE_types.ts | 14 ++- backend/_documentsConfig.ts | 29 +++++- backend/models.ts | 201 +++++++++++++++++++++--------------- 3 files changed, 152 insertions(+), 92 deletions(-) diff --git a/backend/BE_types.ts b/backend/BE_types.ts index 12cb0828..26d3090f 100644 --- a/backend/BE_types.ts +++ b/backend/BE_types.ts @@ -40,6 +40,8 @@ export type BackendObjType = { export enum DBType { Postgres = 'pg', MySQL = 'mysql', + RDSPostgres = 'rds-pg', + RDSMySQL = 'rds-mysql' } export enum LogType { @@ -58,8 +60,12 @@ export interface DocConfigFile { pg_user: string; pg_pass: string; pg_port: number | string; - rds_host: string; - rds_user: string; - rds_pass: string; - rds_port: string | number; + rds_mysql_host: string; + rds_mysql_user: string; + rds_mysql_pass: string; + rds_mysql_port: number | string; + rds_pg_host: string; + rds_pg_user: string; + rds_pg_pass: string; + rds_pg_port: number | string; } diff --git a/backend/_documentsConfig.ts b/backend/_documentsConfig.ts index 0562e263..ba219e09 100644 --- a/backend/_documentsConfig.ts +++ b/backend/_documentsConfig.ts @@ -21,10 +21,14 @@ const writeConfigDefault = function (): DocConfigFile { pg_user: 'postgres', pg_pass: 'postgres', pg_port: 5432, - rds_host: 'AWS RDS', - rds_user: 'RDS', - rds_pass: 'password', - rds_port: 'Port', + rds_mysql_host: 'AWS RDS', + rds_mysql_user: 'RDS', + rds_mysql_pass: 'password', + rds_mysql_port: 3306, + rds_pg_host: 'AWS RDS', + rds_pg_user: 'RDS', + rds_pg_pass: 'password', + rds_pg_port: 5432, }; fs.writeFileSync(configPath, JSON.stringify(defaultFile)); @@ -95,6 +99,23 @@ const docConfig: DocConfig = { port: configFile.mysql_port, }; } + if( dbType === DBType.RDSMySQL) { // added grabbing RDSMySQL credentials + return { + host: configFile.rds_mysql_host, + user: configFile.rds_mysql_user, + pass: configFile.rds_mysql_pass, + port: configFile.rds_mysql_port, + }; + } + if( dbType === DBType.RDSPostgres) { // added grabbing RDSPG credentials + return { + host: configFile.rds_pg_host, + user: configFile.rds_pg_user, + pass: configFile.rds_pg_pass, + port: configFile.rds_pg_port, + }; + } + logger('Could not get credentials of DBType: ', LogType.ERROR, dbType); return { user: 'none', pass: 'none', port: 1 }; }, diff --git a/backend/models.ts b/backend/models.ts index c194dc04..0a41ac06 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -43,7 +43,11 @@ const getColumnObjects = function ( const value = [tableName]; - if (dbType === DBType.Postgres) { + if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { // added to check for RDS + + let pool; // changes which pool is being queried based on dbType + if(dbType === DBType.Postgres) pool = pg_pool; + if(dbType === DBType.RDSPostgres) pool = rds_pg_pool; // query string to get constraints and table references as well queryString = `SELECT DISTINCT cols.column_name, cols.data_type, @@ -65,12 +69,12 @@ const getColumnObjects = function ( ON rco.unique_constraint_name = rel_kcu.constraint_name WHERE cols.table_name = $1`; - //kcu = key column usage = describes which key columns have constraints - //tc = table constraints = shows if constraint is primary key or foreign key - //information_schema.table_constraints show the whole table constraints + // kcu = key column usage = describes which key columns have constraints + // tc = table constraints = shows if constraint is primary key or foreign key + // information_schema.table_constraints show the whole table constraints return new Promise((resolve, reject) => { - pg_pool + pool .query(queryString, value) .then((result) => { const columnInfoArray: ColumnObj[] = []; @@ -83,7 +87,11 @@ const getColumnObjects = function ( reject(err); }); }); - } else if (dbType === DBType.MySQL) { + } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { // added to check for RDS + + let pool; // changes which pool is being queried based on dbType + if(dbType === DBType.MySQL) pool = msql_pool; + if(dbType === DBType.RDSMySQL) pool = rds_msql_pool; queryString = `SELECT DISTINCT cols.column_name AS column_name, cols.data_type AS data_type, @@ -133,13 +141,18 @@ const getColumnObjects = function ( const getDBNames = function (dbType: DBType): Promise { return new Promise((resolve, reject) => { let query; - if (dbType === DBType.Postgres) { + if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { + + let pool; // changes which pool is being queried based on dbType + if(dbType === DBType.Postgres) pool = pg_pool; + if(dbType === DBType.RDSPostgres) pool = rds_pg_pool; + query = `SELECT dbs.datname AS db_name, pg_size_pretty(pg_database_size(dbs.datname)) AS db_size FROM pg_database dbs ORDER BY db_name`; - pg_pool + pool .query(query) .then((databases) => { const dbList: dbDetails[] = []; @@ -165,7 +178,7 @@ const getDBNames = function (dbType: DBType): Promise { .catch((err) => { reject(err); }); - } else if (dbType === DBType.MySQL) { + } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { // added to check for RDS // query = ` // SELECT table_schema db_name, // ROUND(SUM(data_length + index_length) / 1024, 1) db_size @@ -173,6 +186,9 @@ const getDBNames = function (dbType: DBType): Promise { // FROM information_schema.tables // WHERE table_schema NOT IN("information_schema", "performance_schema", "mysql", "sys") // GROUP BY table_schema;`; + let pool; + if(dbType === DBType.MySQL) pool = msql_pool; + if(dbType === DBType.RDSMySQL) pool = rds_msql_pool; query = ` SELECT @@ -187,7 +203,7 @@ const getDBNames = function (dbType: DBType): Promise { GROUP BY S.SCHEMA_NAME ORDER BY db_name ASC;`; - msql_pool + pool .query(query) .then((databases) => { const dbList: dbDetails[] = []; @@ -228,7 +244,12 @@ const getDBLists = function ( // console.log('dbType - getDBLists: ', dbType); - if (dbType === DBType.Postgres) { + if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { + + let pool; + if(dbType === DBType.Postgres) pool = pg_pool; + if(dbType === DBType.RDSPostgres) pool = rds_pg_pool; + query = `SELECT table_catalog, table_schema, @@ -238,7 +259,7 @@ const getDBLists = function ( WHERE table_schema = 'public' or table_schema = 'base' ORDER BY table_name;`; - pg_pool + pool .query(query) .then((tables) => { for (let i = 0; i < tables.rows.length; i++) { @@ -264,10 +285,15 @@ const getDBLists = function ( .catch((err) => { reject(err); }); - } else if (dbType === DBType.MySQL) { + } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { // Notice that TABLE_CATALOG is set to table_schema // And that TABLE_SCHEMA is set to table_catalog // This is because PG and MySQL have these flipped (For whatever reason) + + let pool; + if(dbType === DBType.MySQL) pool = msql_pool; + if(dbType === DBType.RDSMySQL) pool = rds_msql_pool; + query = `SELECT TABLE_CATALOG as table_schema, TABLE_SCHEMA as table_catalog, @@ -277,7 +303,7 @@ const getDBLists = function ( AND TABLE_SCHEMA = "${dbName}" ORDER BY table_name;`; - msql_pool + pool .query(query) .then((tables) => { for (let i = 0; i < tables[0].length; i++) { @@ -335,11 +361,35 @@ const MSQL_DBConnect = function (db: string) { }); }; +// const RDS_PG_DBConnect = async function (pg_uri: string, db: string) { +// const newURI = `${pg_uri}${db}`; +// const newPool = new Pool({ connectionString: newURI }); +// if (rds_pg_pool) await rds_pg_pool.end(); +// rds_pg_pool = newPool; + +// logger(`New pool URI set: ${newURI}`, LogType.SUCCESS); +// } +// // DOES THIS NEED A URI? + +// const RDS_MSQL_DBConnect = function (db: string) { +// rds_msql_pool +// .query(`USE ${db};`) +// .then(() => { +// logger(`Connected to RDS MSQL DB: ${db}`, LogType.SUCCESS); +// }) +// .catch((err) => { +// logger(`Couldnt connect to RDS MSQL DB: ${db}`, LogType.ERROR); +// }); +// } + // *********************************************************** MAIN QUERY FUNCTIONS ************************************************* // interface MyObj { pg_uri: string; + rds_pg_uri: string; curPG_DB: string; curMSQL_DB: string; + curRDS_MSQL_DB: string; + curRDS_PG_DB: string; setBaseConnections: () => Promise; query: ( text: string, @@ -354,61 +404,60 @@ interface MyObj { // eslint-disable-next-line prefer-const const myObj: MyObj = { pg_uri: '', + rds_pg_uri: '', curPG_DB: '', curMSQL_DB: '', + curRDS_MSQL_DB: '', + curRDS_PG_DB: '', + // Setting starting connection async setBaseConnections() { const PG_Cred = docConfig.getCredentials(DBType.Postgres); const MSQL_Cred = docConfig.getCredentials(DBType.MySQL); - //JUNAID - //destructuring rds creds from docConfig.getFullConfig. Doing it this way for now so that i dont have to go back and change the types for the docConfig and create another method to send just the RDS Credentials. can refactor later. - const { rds_host, rds_user, rds_pass, rds_port } = - docConfig.getFullConfig(); - const RDS_Creds = { - host: rds_host, - user: rds_user, - password: rds_pass, - port: rds_port, - }; - - //JUNAID - //one is commented out rn bc we can only connect to one cloud db at a time since we only have one text field for the cloud. also we need to add new vars and types for the second cloud connection. both cloud connections can use the same format as the current RDS_CREDS var - - //rds pg pool conn - if (rds_pg_pool) { - await rds_pg_pool.end(); - } - // rds_pg_pool = new Pool({ ...RDS_Creds }); - // console.log(RDS_Creds); - // rds_pg_pool.connect((err) => { - // if (err) { - // console.log(err, 'ERR PG'); - // } else { - // console.log('connected to db'); - // } - // }); - - //rds msql pool conn - if (rds_msql_pool) { - await rds_msql_pool.end(); + const RDS_PG_Cred = docConfig.getCredentials(DBType.RDSPostgres); + const RDS_MSQL_Cred = docConfig.getCredentials(DBType.RDSMySQL); + + // this is a dum solution but it needs to be passed in as password into the pool + // and i would rather do it here than in the documentsconfig file + const RDS_MSQL_INFO = { + host: RDS_MSQL_Cred.host, + user: RDS_MSQL_Cred.user, + password: RDS_MSQL_Cred.pass, + port: RDS_MSQL_Cred.port, } - rds_msql_pool = mysql.createPool({ ...RDS_Creds }); - //just a test query to make sure were connected (it works, i tested with other queries creating tables too) - const q = await rds_msql_pool.query('SHOW DATABASES;'); + const RDS_PG_INFO = { + host: RDS_PG_Cred.host, + user: RDS_PG_Cred.user, + password: RDS_PG_Cred.pass, + port: RDS_PG_Cred.port, + } + // RDS PG POOL + if (rds_pg_pool) await rds_pg_pool.end(); + rds_pg_pool = new Pool({ ...RDS_PG_INFO }); + rds_pg_pool.connect((err) => { + if (err) console.log(err, 'ERR PG'); + else console.log('connected to db'); + }); + + // RDS MSQL POOL + if (rds_msql_pool) await rds_msql_pool.end(); + rds_msql_pool = mysql.createPool({ ...RDS_MSQL_INFO }); + const q = await rds_msql_pool.query('SHOW DATABASES;'); // just a test query to make sure were connected (it works, i tested with other queries creating tables too) console.log(q, 'q'); // URI Format: postgres://username:password@hostname:port/databasename // Note User must have a 'postgres'role set-up prior to initializing this connection. https://www.postgresql.org/docs/13/database-roles.html // ^Unknown if this rule is still true - if (pg_pool) await pg_pool.end(); + // LOCAL PG POOL + if (pg_pool) await pg_pool.end(); this.pg_uri = `postgres://${PG_Cred.user}:${PG_Cred.pass}@localhost:${PG_Cred.port}/`; pg_pool = new Pool({ connectionString: this.pg_uri + this.curPG_DB }); + // LOCAL MSQL POOL if (msql_pool) await msql_pool.end(); - msql_pool = mysql.createPool({ host: `localhost`, port: MSQL_Cred.port, @@ -476,10 +525,7 @@ const myObj: MyObj = { // Change current Db async connectToDB(db: string, dbType?: DBType | undefined) { - logger( - `Starting connect to DB: ${db} With a dbType of: ${dbType?.toString()} and lastDBType is ${lastDBType}` - ); - + logger(`Starting connect to DB: ${db} With a dbType of: ${dbType?.toString()} and lastDBType is ${lastDBType}`); if (!dbType) { if (!lastDBType) { logger( @@ -498,7 +544,16 @@ const myObj: MyObj = { // console.log(`connectToDB -- : ${this.curMSQL_DB}`); this.curMSQL_DB = db; await MSQL_DBConnect(db); - } + } + // else if (dbType === DBType.RDSMySQL) { + // this.curRDS_MSQL_DB = db; + // await RDS_MSQL_DBConnect(db); + // } + // else if (dbType === DBType.RDSPostgres) { + // this.curRDS_PG_DB = db; + // await RDS_PG_DBConnect(this.rds_pg_uri, db); + // // DOES THIS NEED A URI? + // } }, // Returns a listObj with two properties using two helpful functions defined above - getDBNames and getDBLists @@ -527,16 +582,12 @@ const myObj: MyObj = { .then((msdata) => { const msqlDBList = msdata; listObj.databaseConnected[1] = true; - logger('Got DB Names for both PG and MySQL!', LogType.SUCCESS); listObj.databaseList = [...pgDBList, ...msqlDBList]; }) .catch((err) => { // MySQL fails... Just get PG! - logger( - "Couldn't connect to MySQL. Sending only PG Data!", - LogType.ERROR - ); + logger("Couldn't connect to MySQL. Sending only PG Data!", LogType.ERROR); listObj.databaseList = pgDBList; }) .finally(() => { @@ -544,18 +595,12 @@ const myObj: MyObj = { // console.log('dbType is defined') getDBLists(dbType, dbName) // dbLists returning empty array - DBType is not defined .then((data) => { - logger( - `RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, - LogType.SUCCESS - ); + logger(`RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, LogType.SUCCESS); listObj.tableList = data; resolve(listObj); }) .catch((err) => { - logger( - `Error getting tableList details: ${err.message}`, - LogType.ERROR - ); + logger(`Error getting tableList details: ${err.message}`, LogType.ERROR); }); } else { // console.log('dbType is not defined') @@ -566,10 +611,7 @@ const myObj: MyObj = { }) .catch((err) => { // If PG fails, try just sending MySQL. - logger( - "Couldn't connect to PG. Attempting to connect to MySQL instead!", - LogType.ERROR - ); + logger("Couldn't connect to PG. Attempting to connect to MySQL instead!", LogType.ERROR); // Get MySQL DBs getDBNames(DBType.MySQL) .then((msdata) => { @@ -579,18 +621,12 @@ const myObj: MyObj = { if (dbType) { getDBLists(dbType, dbName) .then((data) => { - logger( - `RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, - LogType.SUCCESS - ); + logger(`RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, LogType.SUCCESS); listObj.tableList = data; resolve(listObj); }) .catch((err) => { - logger( - `Error getting tableList details: ${err.message}`, - LogType.ERROR - ); + logger(`Error getting tableList details: ${err.message}`, LogType.ERROR); }); } else { logger('RESOLVING DB DETAILS: Only DB Names', LogType.SUCCESS); @@ -598,10 +634,7 @@ const myObj: MyObj = { } }) .catch((err) => { - logger( - `Could not connect to either PG or MySQL: ${err.message}`, - LogType.ERROR - ); + logger(`Could not connect to either PG or MySQL: ${err.message}`, LogType.ERROR); throw err; }); }); From 55e3513ed3e673ef6f2d84cb77184c9f9a3ad6af Mon Sep 17 00:00:00 2001 From: ChaseSizemore Date: Thu, 30 Mar 2023 17:04:49 -0400 Subject: [PATCH 05/10] 'small change' --- backend/models.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/models.ts b/backend/models.ts index 0a41ac06..f10eea1c 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -438,14 +438,14 @@ const myObj: MyObj = { rds_pg_pool = new Pool({ ...RDS_PG_INFO }); rds_pg_pool.connect((err) => { if (err) console.log(err, 'ERR PG'); - else console.log('connected to db'); + else console.log('connected to pgdb'); }); // RDS MSQL POOL if (rds_msql_pool) await rds_msql_pool.end(); rds_msql_pool = mysql.createPool({ ...RDS_MSQL_INFO }); const q = await rds_msql_pool.query('SHOW DATABASES;'); // just a test query to make sure were connected (it works, i tested with other queries creating tables too) - console.log(q, 'q'); + console.log(q[0], 'q'); // URI Format: postgres://username:password@hostname:port/databasename // Note User must have a 'postgres'role set-up prior to initializing this connection. https://www.postgresql.org/docs/13/database-roles.html From b18ad4dcd4814ba09b3c9318378e1bc7689c749f Mon Sep 17 00:00:00 2001 From: ChaseSizemore Date: Thu, 30 Mar 2023 19:13:15 -0400 Subject: [PATCH 06/10] added react dev tools --- backend/main.ts | 9 ++++++--- backend/models.ts | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/backend/main.ts b/backend/main.ts index 0550e7a0..7a9d138f 100644 --- a/backend/main.ts +++ b/backend/main.ts @@ -1,10 +1,10 @@ // eslint-disable-next-line import/no-extraneous-dependencies import { BrowserWindow, Menu } from 'electron'; -const { app } = require('electron'); +const { app, session } = require('electron'); const dev: boolean = process.env.NODE_ENV === 'development'; - +const os = require('os'); const path = require('path'); const url = require('url'); const fixPath = require('fix-path'); @@ -16,7 +16,10 @@ require('./channels'); fixPath(); // Keep a global reference of the window objects, if you don't, the window will be closed automatically when the JavaScript object is garbage collected. let mainWindow: BrowserWindow | null; - +const reactDevToolsPath = path.join(os.homedir(), '/Desktop/ReactDevTools'); +app.whenReady().then(async () => { + await session.defaultSession.loadExtension(reactDevToolsPath); +}); function createWindow() { mainWindow = new BrowserWindow({ width: 1800, diff --git a/backend/models.ts b/backend/models.ts index f10eea1c..1040dd76 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -584,6 +584,7 @@ const myObj: MyObj = { listObj.databaseConnected[1] = true; logger('Got DB Names for both PG and MySQL!', LogType.SUCCESS); listObj.databaseList = [...pgDBList, ...msqlDBList]; + }) .catch((err) => { // MySQL fails... Just get PG! From 807637d7456ce9746f6f90101d9e8f268335698f Mon Sep 17 00:00:00 2001 From: ChaseSizemore Date: Sat, 1 Apr 2023 15:02:37 -0400 Subject: [PATCH 07/10] fixed connect functions and looked at lists --- backend/BE_types.ts | 4 +- backend/connections.ts | 0 backend/models.ts | 163 ++++++++++++++++++++++------------------- 3 files changed, 91 insertions(+), 76 deletions(-) create mode 100644 backend/connections.ts diff --git a/backend/BE_types.ts b/backend/BE_types.ts index 26d3090f..0afa0ab9 100644 --- a/backend/BE_types.ts +++ b/backend/BE_types.ts @@ -25,7 +25,7 @@ export interface TableDetails { columns?: ColumnObj[]; } export interface DBList { - databaseConnected: boolean[]; + databaseConnected: [boolean, boolean]; databaseList: dbDetails[]; tableList: TableDetails[]; } @@ -41,7 +41,7 @@ export enum DBType { Postgres = 'pg', MySQL = 'mysql', RDSPostgres = 'rds-pg', - RDSMySQL = 'rds-mysql' + RDSMySQL = 'rds-mysql', } export enum LogType { diff --git a/backend/connections.ts b/backend/connections.ts new file mode 100644 index 00000000..e69de29b diff --git a/backend/models.ts b/backend/models.ts index 1040dd76..148a9e49 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -43,11 +43,12 @@ const getColumnObjects = function ( const value = [tableName]; - if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { // added to check for RDS + if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { + // added to check for RDS let pool; // changes which pool is being queried based on dbType - if(dbType === DBType.Postgres) pool = pg_pool; - if(dbType === DBType.RDSPostgres) pool = rds_pg_pool; + if (dbType === DBType.Postgres) pool = pg_pool; + if (dbType === DBType.RDSPostgres) pool = rds_pg_pool; // query string to get constraints and table references as well queryString = `SELECT DISTINCT cols.column_name, cols.data_type, @@ -87,11 +88,12 @@ const getColumnObjects = function ( reject(err); }); }); - } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { // added to check for RDS + } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { + // added to check for RDS let pool; // changes which pool is being queried based on dbType - if(dbType === DBType.MySQL) pool = msql_pool; - if(dbType === DBType.RDSMySQL) pool = rds_msql_pool; + if (dbType === DBType.MySQL) pool = msql_pool; + if (dbType === DBType.RDSMySQL) pool = rds_msql_pool; queryString = `SELECT DISTINCT cols.column_name AS column_name, cols.data_type AS data_type, @@ -141,11 +143,10 @@ const getColumnObjects = function ( const getDBNames = function (dbType: DBType): Promise { return new Promise((resolve, reject) => { let query; - if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { - + if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { let pool; // changes which pool is being queried based on dbType - if(dbType === DBType.Postgres) pool = pg_pool; - if(dbType === DBType.RDSPostgres) pool = rds_pg_pool; + if (dbType === DBType.Postgres) pool = pg_pool; + if (dbType === DBType.RDSPostgres) pool = rds_pg_pool; query = `SELECT dbs.datname AS db_name, pg_size_pretty(pg_database_size(dbs.datname)) AS db_size @@ -178,7 +179,8 @@ const getDBNames = function (dbType: DBType): Promise { .catch((err) => { reject(err); }); - } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { // added to check for RDS + } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { + // added to check for RDS // query = ` // SELECT table_schema db_name, // ROUND(SUM(data_length + index_length) / 1024, 1) db_size @@ -187,8 +189,8 @@ const getDBNames = function (dbType: DBType): Promise { // WHERE table_schema NOT IN("information_schema", "performance_schema", "mysql", "sys") // GROUP BY table_schema;`; let pool; - if(dbType === DBType.MySQL) pool = msql_pool; - if(dbType === DBType.RDSMySQL) pool = rds_msql_pool; + if (dbType === DBType.MySQL) pool = msql_pool; + if (dbType === DBType.RDSMySQL) pool = rds_msql_pool; query = ` SELECT @@ -245,10 +247,9 @@ const getDBLists = function ( // console.log('dbType - getDBLists: ', dbType); if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { - let pool; - if(dbType === DBType.Postgres) pool = pg_pool; - if(dbType === DBType.RDSPostgres) pool = rds_pg_pool; + if (dbType === DBType.Postgres) pool = pg_pool; + if (dbType === DBType.RDSPostgres) pool = rds_pg_pool; query = `SELECT table_catalog, @@ -291,8 +292,8 @@ const getDBLists = function ( // This is because PG and MySQL have these flipped (For whatever reason) let pool; - if(dbType === DBType.MySQL) pool = msql_pool; - if(dbType === DBType.RDSMySQL) pool = rds_msql_pool; + if (dbType === DBType.MySQL) pool = msql_pool; + if (dbType === DBType.RDSMySQL) pool = rds_msql_pool; query = `SELECT TABLE_CATALOG as table_schema, @@ -342,15 +343,23 @@ let lastDBType: DBType | undefined; const PG_DBConnect = async function (pg_uri: string, db: string) { const newURI = `${pg_uri}${db}`; + console.log(newURI, 'newURI'); const newPool = new Pool({ connectionString: newURI }); if (pg_pool) await pg_pool.end(); pg_pool = newPool; logger(`New pool URI set: ${newURI}`, LogType.SUCCESS); + // return newPool; +}; + +const MSQL_DBConnect = async function (MYSQL_CREDS: any) { + if (msql_pool) await msql_pool.end(); + msql_pool = mysql.createPool({ ...MYSQL_CREDS }); }; -const MSQL_DBConnect = function (db: string) { +const MSQL_DBQuery = function (db: string) { // console.log(`mysql dbconnect ${db}`); + msql_pool .query(`USE ${db};`) .then(() => { @@ -361,26 +370,21 @@ const MSQL_DBConnect = function (db: string) { }); }; -// const RDS_PG_DBConnect = async function (pg_uri: string, db: string) { -// const newURI = `${pg_uri}${db}`; -// const newPool = new Pool({ connectionString: newURI }); -// if (rds_pg_pool) await rds_pg_pool.end(); -// rds_pg_pool = newPool; - -// logger(`New pool URI set: ${newURI}`, LogType.SUCCESS); -// } -// // DOES THIS NEED A URI? - -// const RDS_MSQL_DBConnect = function (db: string) { -// rds_msql_pool -// .query(`USE ${db};`) -// .then(() => { -// logger(`Connected to RDS MSQL DB: ${db}`, LogType.SUCCESS); -// }) -// .catch((err) => { -// logger(`Couldnt connect to RDS MSQL DB: ${db}`, LogType.ERROR); -// }); -// } +const RDS_PG_DBConnect = async function (RDS_PG_INFO) { + if (rds_pg_pool) await rds_pg_pool.end(); + rds_pg_pool = new Pool({ ...RDS_PG_INFO }); + rds_pg_pool.connect((err) => { + if (err) console.log(err, 'ERR PG'); + else console.log('connected to pgdb'); + }); +}; + +const RDS_MSQL_DBConnect = async function (RDS_MSQL_INFO) { + if (rds_msql_pool) await rds_msql_pool.end(); + rds_msql_pool = mysql.createPool({ ...RDS_MSQL_INFO }); + const q = await rds_msql_pool.query('SHOW DATABASES;'); // just a test query to make sure were connected (it works, i tested with other queries creating tables too) + console.log(q[0], 'q'); +}; // *********************************************************** MAIN QUERY FUNCTIONS ************************************************* // interface MyObj { @@ -409,7 +413,6 @@ const myObj: MyObj = { curMSQL_DB: '', curRDS_MSQL_DB: '', curRDS_PG_DB: '', - // Setting starting connection async setBaseConnections() { @@ -425,40 +428,31 @@ const myObj: MyObj = { user: RDS_MSQL_Cred.user, password: RDS_MSQL_Cred.pass, port: RDS_MSQL_Cred.port, - } + }; const RDS_PG_INFO = { host: RDS_PG_Cred.host, user: RDS_PG_Cred.user, password: RDS_PG_Cred.pass, port: RDS_PG_Cred.port, - } + }; + // RDS PG POOL - if (rds_pg_pool) await rds_pg_pool.end(); - rds_pg_pool = new Pool({ ...RDS_PG_INFO }); - rds_pg_pool.connect((err) => { - if (err) console.log(err, 'ERR PG'); - else console.log('connected to pgdb'); - }); + await RDS_PG_DBConnect(RDS_PG_INFO); // RDS MSQL POOL - if (rds_msql_pool) await rds_msql_pool.end(); - rds_msql_pool = mysql.createPool({ ...RDS_MSQL_INFO }); - const q = await rds_msql_pool.query('SHOW DATABASES;'); // just a test query to make sure were connected (it works, i tested with other queries creating tables too) - console.log(q[0], 'q'); + await RDS_MSQL_DBConnect(RDS_MSQL_INFO); // URI Format: postgres://username:password@hostname:port/databasename // Note User must have a 'postgres'role set-up prior to initializing this connection. https://www.postgresql.org/docs/13/database-roles.html // ^Unknown if this rule is still true // LOCAL PG POOL - if (pg_pool) await pg_pool.end(); this.pg_uri = `postgres://${PG_Cred.user}:${PG_Cred.pass}@localhost:${PG_Cred.port}/`; - pg_pool = new Pool({ connectionString: this.pg_uri + this.curPG_DB }); + await PG_DBConnect(this.pg_uri, this.curPG_DB); // LOCAL MSQL POOL - if (msql_pool) await msql_pool.end(); - msql_pool = mysql.createPool({ + await MSQL_DBConnect({ host: `localhost`, port: MSQL_Cred.port, user: MSQL_Cred.user, @@ -525,7 +519,9 @@ const myObj: MyObj = { // Change current Db async connectToDB(db: string, dbType?: DBType | undefined) { - logger(`Starting connect to DB: ${db} With a dbType of: ${dbType?.toString()} and lastDBType is ${lastDBType}`); + logger( + `Starting connect to DB: ${db} With a dbType of: ${dbType?.toString()} and lastDBType is ${lastDBType}` + ); if (!dbType) { if (!lastDBType) { logger( @@ -541,17 +537,16 @@ const myObj: MyObj = { this.curPG_DB = db; await PG_DBConnect(this.pg_uri, db); } else if (dbType === DBType.MySQL) { - // console.log(`connectToDB -- : ${this.curMSQL_DB}`); this.curMSQL_DB = db; - await MSQL_DBConnect(db); - } - // else if (dbType === DBType.RDSMySQL) { - // this.curRDS_MSQL_DB = db; - // await RDS_MSQL_DBConnect(db); - // } + + await MSQL_DBQuery(db); + } else if (dbType === DBType.RDSMySQL) { + this.curRDS_MSQL_DB = db; + await RDS_MSQL_DBConnect(db); + } // else if (dbType === DBType.RDSPostgres) { // this.curRDS_PG_DB = db; - // await RDS_PG_DBConnect(this.rds_pg_uri, db); + // await RDS_PG_DBConnect(this.rds_pg_uri, db); // // DOES THIS NEED A URI? // } }, @@ -576,7 +571,6 @@ const myObj: MyObj = { .then((pgdata) => { const pgDBList = pgdata; listObj.databaseConnected[0] = true; - // Get MySQL DBs getDBNames(DBType.MySQL) .then((msdata) => { @@ -584,24 +578,33 @@ const myObj: MyObj = { listObj.databaseConnected[1] = true; logger('Got DB Names for both PG and MySQL!', LogType.SUCCESS); listObj.databaseList = [...pgDBList, ...msqlDBList]; - }) .catch((err) => { // MySQL fails... Just get PG! - logger("Couldn't connect to MySQL. Sending only PG Data!", LogType.ERROR); + logger( + "Couldn't connect to MySQL. Sending only PG Data!", + LogType.ERROR + ); listObj.databaseList = pgDBList; }) .finally(() => { + console.log(dbType, dbName, 'finally'); if (dbType) { // console.log('dbType is defined') getDBLists(dbType, dbName) // dbLists returning empty array - DBType is not defined .then((data) => { - logger(`RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, LogType.SUCCESS); + logger( + `RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, + LogType.SUCCESS + ); listObj.tableList = data; resolve(listObj); }) .catch((err) => { - logger(`Error getting tableList details: ${err.message}`, LogType.ERROR); + logger( + `Error getting tableList details: ${err.message}`, + LogType.ERROR + ); }); } else { // console.log('dbType is not defined') @@ -612,7 +615,10 @@ const myObj: MyObj = { }) .catch((err) => { // If PG fails, try just sending MySQL. - logger("Couldn't connect to PG. Attempting to connect to MySQL instead!", LogType.ERROR); + logger( + "Couldn't connect to PG. Attempting to connect to MySQL instead!", + LogType.ERROR + ); // Get MySQL DBs getDBNames(DBType.MySQL) .then((msdata) => { @@ -622,12 +628,18 @@ const myObj: MyObj = { if (dbType) { getDBLists(dbType, dbName) .then((data) => { - logger(`RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, LogType.SUCCESS); + logger( + `RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, + LogType.SUCCESS + ); listObj.tableList = data; resolve(listObj); }) .catch((err) => { - logger(`Error getting tableList details: ${err.message}`, LogType.ERROR); + logger( + `Error getting tableList details: ${err.message}`, + LogType.ERROR + ); }); } else { logger('RESOLVING DB DETAILS: Only DB Names', LogType.SUCCESS); @@ -635,7 +647,10 @@ const myObj: MyObj = { } }) .catch((err) => { - logger(`Could not connect to either PG or MySQL: ${err.message}`, LogType.ERROR); + logger( + `Could not connect to either PG or MySQL: ${err.message}`, + LogType.ERROR + ); throw err; }); }); From a11301bfed4fa36b673efe19d94948eb3be0bc62 Mon Sep 17 00:00:00 2001 From: Junaid Ahmed Date: Sun, 2 Apr 2023 00:04:14 -0400 Subject: [PATCH 08/10] cloud queries seem to be working, still lots to test and refactor --- backend/BE_types.ts | 2 +- backend/connections.ts | 0 backend/databaseConnections.ts | 65 ++++++++++++ backend/models.ts | 177 +++++++++++++++++++-------------- 4 files changed, 171 insertions(+), 73 deletions(-) delete mode 100644 backend/connections.ts create mode 100644 backend/databaseConnections.ts diff --git a/backend/BE_types.ts b/backend/BE_types.ts index 0afa0ab9..23a7025f 100644 --- a/backend/BE_types.ts +++ b/backend/BE_types.ts @@ -25,7 +25,7 @@ export interface TableDetails { columns?: ColumnObj[]; } export interface DBList { - databaseConnected: [boolean, boolean]; + databaseConnected: [boolean, boolean, boolean, boolean]; databaseList: dbDetails[]; tableList: TableDetails[]; } diff --git a/backend/connections.ts b/backend/connections.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/databaseConnections.ts b/backend/databaseConnections.ts new file mode 100644 index 00000000..b5c79fd9 --- /dev/null +++ b/backend/databaseConnections.ts @@ -0,0 +1,65 @@ +//ATTEMPT AT EXTRACTING TO ANOTHER FILE, NOT WORKING YET :( + +const poolVariables = require('./models'); +const { Pool } = require('pg'); +const mysql = require('mysql2/promise'); +import logger from './Logging/masterlog'; +import { LogType } from './BE_types'; + +module.exports = { + PG_DBConnect: async function (pg_uri: string, db: string) { + const newURI = `${pg_uri}${db}`; + const newPool = new Pool({ connectionString: newURI }); + if (poolVariables.pools.pg_pool) await poolVariables.pools.pg_pool.end(); + poolVariables.pools.pg_pool = newPool; + logger(`New pool URI set: ${newURI}`, LogType.SUCCESS); + }, + + MSQL_DBConnect: async function (MYSQL_CREDS: any) { + if (poolVariables.pools.msql_pool) + await poolVariables.pools.msql_pool.end(); + poolVariables.pools.msql_pool = mysql.createPool({ ...MYSQL_CREDS }); + }, + + MSQL_DBQuery: function (db: string) { + poolVariables.pools.msql_pool + .query(`USE ${db};`) + .then(() => { + logger(`Connected to MSQL DB: ${db}`, LogType.SUCCESS); + }) + .catch((err) => { + logger(`Couldnt connect to MSQL DB: ${db}`, LogType.ERROR); + }); + }, + + RDS_PG_DBConnect: async function (RDS_PG_INFO) { + poolVariables.pools.rds_pg_pool = new Pool({ ...RDS_PG_INFO }); + poolVariables.pools.rds_pg_pool.connect((err) => { + if (err) console.log(err, 'ERR PG'); + else console.log('CONNECTED TO RDS PG DATABASE!'); + }); + }, + + RDS_MSQL_DBConnect: async function (RDS_MSQL_INFO) { + if (poolVariables.pools.rds_msql_pool) + await poolVariables.pools.rds_msql_pool.end(); + poolVariables.pools.rds_msql_pool = mysql.createPool({ ...RDS_MSQL_INFO }); + const testQuery = await poolVariables.pools.rds_msql_pool.query( + 'SHOW DATABASES;' + ); // just a test query to make sure were connected (it works, i tested with other queries creating tables too) + console.log( + `CONNECTED TO RDS ${testQuery[0][1].Database.toUpperCase()} DATABASE!` + ); + }, + + RDS_MSQL_DBQuery: function (db: string) { + poolVariables.pools.rds_msql_pool + .query(`USE ${db};`) + .then(() => { + logger(`Connected to MSQL DB: ${db}`, LogType.SUCCESS); + }) + .catch((err) => { + logger(`Couldnt connect to MSQL DB: ${db}`, LogType.ERROR); + }); + }, +}; diff --git a/backend/models.ts b/backend/models.ts index 148a9e49..c16a87d8 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -1,12 +1,3 @@ -/* eslint-disable no-shadow */ -/* eslint-disable func-names */ -/* eslint-disable no-plusplus */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable no-else-return */ -/* eslint-disable no-console */ -import { rejects } from 'assert'; -import { resolve } from 'path'; -import DbList from '../frontend/components/sidebar/DbList'; import { ColumnObj, dbDetails, @@ -15,10 +6,18 @@ import { DBType, LogType, } from './BE_types'; -import logger from './Logging/masterlog'; - +// const { +// PG_DBConnect, +// MSQL_DBConnect, +// MSQL_DBQuery, +// RDS_PG_DBConnect, +// RDS_MSQL_DBConnect, +// RDS_MSQL_DBQuery, +// } = require('./databaseConnections'); const { Pool } = require('pg'); const mysql = require('mysql2/promise'); +import logger from './Logging/masterlog'; + const docConfig = require('./_documentsConfig'); // commented out because queries are no longer being used but good to keep as a reference @@ -140,11 +139,15 @@ const getColumnObjects = function ( // function that gets the name and size of each of the databases in the current postgres instance // ignoring the postgres, template0 and template1 DBs +//JUNAID +//function seems to run four times every time you launch electron or click on any db const getDBNames = function (dbType: DBType): Promise { return new Promise((resolve, reject) => { + console.log('in get dbNames'); let query; if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { let pool; // changes which pool is being queried based on dbType + if (dbType === DBType.Postgres) pool = pg_pool; if (dbType === DBType.RDSPostgres) pool = rds_pg_pool; @@ -152,7 +155,6 @@ const getDBNames = function (dbType: DBType): Promise { pg_size_pretty(pg_database_size(dbs.datname)) AS db_size FROM pg_database dbs ORDER BY db_name`; - pool .query(query) .then((databases) => { @@ -191,7 +193,6 @@ const getDBNames = function (dbType: DBType): Promise { let pool; if (dbType === DBType.MySQL) pool = msql_pool; if (dbType === DBType.RDSMySQL) pool = rds_msql_pool; - query = ` SELECT S.SCHEMA_NAME db_name, @@ -225,6 +226,7 @@ const getDBNames = function (dbType: DBType): Promise { logger("MySQL 'getDBNames' resolved.", LogType.SUCCESS); // resolve with array of db names + resolve(dbList); }) .catch((err) => { @@ -244,8 +246,6 @@ const getDBLists = function ( const tableList: TableDetails[] = []; const promiseArray: Promise[] = []; - // console.log('dbType - getDBLists: ', dbType); - if (dbType === DBType.Postgres || dbType === DBType.RDSPostgres) { let pool; if (dbType === DBType.Postgres) pool = pg_pool; @@ -343,13 +343,10 @@ let lastDBType: DBType | undefined; const PG_DBConnect = async function (pg_uri: string, db: string) { const newURI = `${pg_uri}${db}`; - console.log(newURI, 'newURI'); const newPool = new Pool({ connectionString: newURI }); if (pg_pool) await pg_pool.end(); pg_pool = newPool; - logger(`New pool URI set: ${newURI}`, LogType.SUCCESS); - // return newPool; }; const MSQL_DBConnect = async function (MYSQL_CREDS: any) { @@ -358,8 +355,6 @@ const MSQL_DBConnect = async function (MYSQL_CREDS: any) { }; const MSQL_DBQuery = function (db: string) { - // console.log(`mysql dbconnect ${db}`); - msql_pool .query(`USE ${db};`) .then(() => { @@ -371,29 +366,40 @@ const MSQL_DBQuery = function (db: string) { }; const RDS_PG_DBConnect = async function (RDS_PG_INFO) { - if (rds_pg_pool) await rds_pg_pool.end(); rds_pg_pool = new Pool({ ...RDS_PG_INFO }); rds_pg_pool.connect((err) => { if (err) console.log(err, 'ERR PG'); - else console.log('connected to pgdb'); + else console.log('CONNECTED TO RDS PG DATABASE!'); }); }; const RDS_MSQL_DBConnect = async function (RDS_MSQL_INFO) { if (rds_msql_pool) await rds_msql_pool.end(); rds_msql_pool = mysql.createPool({ ...RDS_MSQL_INFO }); - const q = await rds_msql_pool.query('SHOW DATABASES;'); // just a test query to make sure were connected (it works, i tested with other queries creating tables too) - console.log(q[0], 'q'); + const testQuery = await rds_msql_pool.query('SHOW DATABASES;'); // just a test query to make sure were connected (it works, i tested with other queries creating tables too) + console.log( + `CONNECTED TO RDS ${testQuery[0][1].Database.toUpperCase()} DATABASE!` + ); +}; + +const RDS_MSQL_DBQuery = function (db: string) { + rds_msql_pool + .query(`USE ${db};`) + .then(() => { + logger(`Connected to MSQL DB: ${db}`, LogType.SUCCESS); + }) + .catch((err) => { + logger(`Couldnt connect to MSQL DB: ${db}`, LogType.ERROR); + }); }; // *********************************************************** MAIN QUERY FUNCTIONS ************************************************* // -interface MyObj { +interface DBFunctions { pg_uri: string; - rds_pg_uri: string; curPG_DB: string; curMSQL_DB: string; - curRDS_MSQL_DB: string; - curRDS_PG_DB: string; + curRDS_MSQL_DB: any; + curRDS_PG_DB: any; setBaseConnections: () => Promise; query: ( text: string, @@ -406,15 +412,15 @@ interface MyObj { } // eslint-disable-next-line prefer-const -const myObj: MyObj = { +const DBFunctions: DBFunctions = { pg_uri: '', - rds_pg_uri: '', curPG_DB: '', curMSQL_DB: '', curRDS_MSQL_DB: '', curRDS_PG_DB: '', - // Setting starting connection + // JUNAID + // start the initial connecttion for all four of our databases. want to extract to a seperate file later on, but not right now. will be a little tricky due to the pool variables that we use throughout the page async setBaseConnections() { const PG_Cred = docConfig.getCredentials(DBType.Postgres); const MSQL_Cred = docConfig.getCredentials(DBType.MySQL); @@ -423,14 +429,14 @@ const myObj: MyObj = { // this is a dum solution but it needs to be passed in as password into the pool // and i would rather do it here than in the documentsconfig file - const RDS_MSQL_INFO = { + this.curRDS_MSQL_DB = { host: RDS_MSQL_Cred.host, user: RDS_MSQL_Cred.user, password: RDS_MSQL_Cred.pass, port: RDS_MSQL_Cred.port, }; - const RDS_PG_INFO = { + this.curRDS_PG_DB = { host: RDS_PG_Cred.host, user: RDS_PG_Cred.user, password: RDS_PG_Cred.pass, @@ -438,10 +444,10 @@ const myObj: MyObj = { }; // RDS PG POOL - await RDS_PG_DBConnect(RDS_PG_INFO); + await RDS_PG_DBConnect(this.curRDS_PG_DB); // RDS MSQL POOL - await RDS_MSQL_DBConnect(RDS_MSQL_INFO); + await RDS_MSQL_DBConnect(this.curRDS_MSQL_DB); // URI Format: postgres://username:password@hostname:port/databasename // Note User must have a 'postgres'role set-up prior to initializing this connection. https://www.postgresql.org/docs/13/database-roles.html @@ -469,7 +475,6 @@ const myObj: MyObj = { query(text, params, dbType: DBType) { logger(`Attempting to run query: \n ${text} for: \n ${dbType}`); - // Checking if database type (dbType) is Postgres if (dbType === DBType.Postgres) { return pg_pool.query(text, params).catch((err) => { @@ -480,7 +485,9 @@ const myObj: MyObj = { // Checking if database type (dbType) is MySQL if (dbType === DBType.MySQL) { return new Promise((resolve, reject) => { + console.log(this.curMSQL_DB, 'are we here twoice?'); if (this.curMSQL_DB) { + console.log('here twice too?'); // MySQL requires you to use the USE query in order to connect to a db and run msql_pool .query(`USE ${this.curMSQL_DB}; ${text}`, params, dbType) @@ -501,6 +508,7 @@ const myObj: MyObj = { }); }); } else { + console.log('are we hitting else>?'); msql_pool // MySQL requires you to use the USE query in order to connect to a db and run .query(text, params, dbType) @@ -518,7 +526,10 @@ const myObj: MyObj = { }, // Change current Db + //JUNAID + //this seems to run when you click on a specific db in the list in electron async connectToDB(db: string, dbType?: DBType | undefined) { + console.log('in connectToDB', ' db => ', db, ' dbType -> ', dbType); logger( `Starting connect to DB: ${db} With a dbType of: ${dbType?.toString()} and lastDBType is ${lastDBType}` ); @@ -532,23 +543,19 @@ const myObj: MyObj = { } dbType = lastDBType; } - if (dbType === DBType.Postgres) { this.curPG_DB = db; await PG_DBConnect(this.pg_uri, db); } else if (dbType === DBType.MySQL) { this.curMSQL_DB = db; - await MSQL_DBQuery(db); } else if (dbType === DBType.RDSMySQL) { this.curRDS_MSQL_DB = db; - await RDS_MSQL_DBConnect(db); + await RDS_MSQL_DBQuery(db); + } else if (dbType === DBType.RDSPostgres) { + // if (rds_pg_pool) await rds_pg_pool.end(); + await RDS_PG_DBConnect(this.curRDS_PG_DB); } - // else if (dbType === DBType.RDSPostgres) { - // this.curRDS_PG_DB = db; - // await RDS_PG_DBConnect(this.rds_pg_uri, db); - // // DOES THIS NEED A URI? - // } }, // Returns a listObj with two properties using two helpful functions defined above - getDBNames and getDBLists @@ -559,10 +566,13 @@ const myObj: MyObj = { // databaseList: { db_name: 'name', db_size: '1000kB' } // tableList: { table_name: 'name', data_type: 'type', columns: [ colObj ], ...etc. } // } + //JUNAID + // this seems to be the first function that runs when electron is launched getLists(dbName: string = '', dbType?: DBType): Promise { return new Promise((resolve, reject) => { + console.log('in getLists', ' db => ', dbName, ' dbType -> ', dbType); const listObj: DBList = { - databaseConnected: [false, false], + databaseConnected: [false, false, false, false], databaseList: [], tableList: [], // current database's tables }; @@ -577,7 +587,48 @@ const myObj: MyObj = { const msqlDBList = msdata; listObj.databaseConnected[1] = true; logger('Got DB Names for both PG and MySQL!', LogType.SUCCESS); - listObj.databaseList = [...pgDBList, ...msqlDBList]; + getDBNames(DBType.RDSPostgres).then((rdspgdata) => { + const rdspgDBList = rdspgdata; + listObj.databaseConnected[2] = true; + getDBNames(DBType.RDSMySQL) + .then((rdsmsqldata) => { + const rdsmsqlDBList = rdsmsqldata; + listObj.databaseConnected[3] = true; + listObj.databaseList = [ + ...pgDBList, + ...msqlDBList, + ...rdspgDBList, + ...rdsmsqlDBList, + ]; + }) + .finally(() => { + if (dbType) { + // console.log('dbType is defined') + getDBLists(dbType, dbName) // dbLists returning empty array - DBType is not defined + .then((data) => { + logger( + `RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, + LogType.SUCCESS + ); + listObj.tableList = data; + resolve(listObj); + }) + .catch((err) => { + logger( + `Error getting tableList details: ${err.message}`, + LogType.ERROR + ); + }); + } else { + // console.log('dbType is not defined') + logger( + 'RESOLVING DB DETAILS: Only DB Names', + LogType.SUCCESS + ); + resolve(listObj); + } + }); + }); }) .catch((err) => { // MySQL fails... Just get PG! @@ -586,31 +637,6 @@ const myObj: MyObj = { LogType.ERROR ); listObj.databaseList = pgDBList; - }) - .finally(() => { - console.log(dbType, dbName, 'finally'); - if (dbType) { - // console.log('dbType is defined') - getDBLists(dbType, dbName) // dbLists returning empty array - DBType is not defined - .then((data) => { - logger( - `RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, - LogType.SUCCESS - ); - listObj.tableList = data; - resolve(listObj); - }) - .catch((err) => { - logger( - `Error getting tableList details: ${err.message}`, - LogType.ERROR - ); - }); - } else { - // console.log('dbType is not defined') - logger('RESOLVING DB DETAILS: Only DB Names', LogType.SUCCESS); - resolve(listObj); - } }); }) .catch((err) => { @@ -659,8 +685,15 @@ const myObj: MyObj = { // Returns an array of columnObj given a tableName getTableInfo(tableName, dbType: DBType) { + console.log('is gettableInfo first?'); return getColumnObjects(tableName, dbType); }, }; -module.exports = myObj; +module.exports = DBFunctions; +// module.exports.pools = { +// pg_pool, +// msql_pool, +// rds_pg_pool, +// rds_msql_pool, +// }; From 4d0a065ea6ce0098e106939f5f06c04d15d290ba Mon Sep 17 00:00:00 2001 From: Junaid Ahmed Date: Mon, 3 Apr 2023 13:36:26 -0400 Subject: [PATCH 09/10] fixed it so that you can login with not all 4 dbs, and it still works. this involved checking for valid data in jsconfig and logging into databases based on that, and also this invlovled checking for whether or not valid pools existed before making any queries --- backend/_documentsConfig.ts | 27 +-- backend/models.ts | 369 ++++++++++++++++++------------------ 2 files changed, 202 insertions(+), 194 deletions(-) diff --git a/backend/_documentsConfig.ts b/backend/_documentsConfig.ts index ba219e09..ebb6878d 100644 --- a/backend/_documentsConfig.ts +++ b/backend/_documentsConfig.ts @@ -15,19 +15,19 @@ const writeConfigDefault = function (): DocConfigFile { logger('Could not find config file. Creating default', LogType.WARNING); const defaultFile: DocConfigFile = { - mysql_user: 'mysql', - mysql_pass: 'mysql', + mysql_user: '', + mysql_pass: '', mysql_port: 3306, - pg_user: 'postgres', - pg_pass: 'postgres', + pg_user: '', + pg_pass: '', pg_port: 5432, - rds_mysql_host: 'AWS RDS', - rds_mysql_user: 'RDS', - rds_mysql_pass: 'password', + rds_mysql_host: '', + rds_mysql_user: '', + rds_mysql_pass: '', rds_mysql_port: 3306, - rds_pg_host: 'AWS RDS', - rds_pg_user: 'RDS', - rds_pg_pass: 'password', + rds_pg_host: '', + rds_pg_user: '', + rds_pg_pass: '', rds_pg_port: 5432, }; @@ -53,7 +53,8 @@ interface DocConfig { getConfigFolder: () => string; getCredentials: (dbType: DBType) => { user: string; - pass: string; + pass?: string; + password?: string; port: number | string; }; getFullConfig: () => Object; @@ -103,7 +104,7 @@ const docConfig: DocConfig = { return { host: configFile.rds_mysql_host, user: configFile.rds_mysql_user, - pass: configFile.rds_mysql_pass, + password: configFile.rds_mysql_pass, port: configFile.rds_mysql_port, }; } @@ -111,7 +112,7 @@ const docConfig: DocConfig = { return { host: configFile.rds_pg_host, user: configFile.rds_pg_user, - pass: configFile.rds_pg_pass, + password: configFile.rds_pg_pass, port: configFile.rds_pg_port, }; } diff --git a/backend/models.ts b/backend/models.ts index c16a87d8..072802e4 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -150,37 +150,40 @@ const getDBNames = function (dbType: DBType): Promise { if (dbType === DBType.Postgres) pool = pg_pool; if (dbType === DBType.RDSPostgres) pool = rds_pg_pool; - - query = `SELECT dbs.datname AS db_name, - pg_size_pretty(pg_database_size(dbs.datname)) AS db_size - FROM pg_database dbs - ORDER BY db_name`; - pool - .query(query) - .then((databases) => { - const dbList: dbDetails[] = []; - - for (let i = 0; i < databases.rows.length; i++) { - const data = databases.rows[i]; - const { db_name } = data; - - if ( - db_name !== 'postgres' && - db_name !== 'template0' && - db_name !== 'template1' - ) { - data.db_type = dbType; - dbList.push(data); + const dbList: dbDetails[] = []; + + if (pool) { + query = `SELECT dbs.datname AS db_name, + pg_size_pretty(pg_database_size(dbs.datname)) AS db_size + FROM pg_database dbs + ORDER BY db_name`; + pool + .query(query) + .then((databases) => { + for (let i = 0; i < databases.rows.length; i++) { + const data = databases.rows[i]; + const { db_name } = data; + + if ( + db_name !== 'postgres' && + db_name !== 'template0' && + db_name !== 'template1' + ) { + data.db_type = dbType; + dbList.push(data); + } } - } - logger("PG 'getDBNames' resolved.", LogType.SUCCESS); - // resolve with array of db names - resolve(dbList); - }) - .catch((err) => { - reject(err); - }); + logger("PG 'getDBNames' resolved.", LogType.SUCCESS); + // resolve with array of db names + resolve(dbList); + }) + .catch((err) => { + reject(err); + }); + } else { + resolve(dbList); + } } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { // added to check for RDS // query = ` @@ -193,50 +196,56 @@ const getDBNames = function (dbType: DBType): Promise { let pool; if (dbType === DBType.MySQL) pool = msql_pool; if (dbType === DBType.RDSMySQL) pool = rds_msql_pool; - query = ` - SELECT - S.SCHEMA_NAME db_name, - ROUND(SUM(data_length + index_length) / 1024, 1) db_size - FROM - INFORMATION_SCHEMA.SCHEMATA S - LEFT OUTER JOIN - INFORMATION_SCHEMA.TABLES T ON S.SCHEMA_NAME = T.TABLE_SCHEMA - WHERE - S.SCHEMA_NAME NOT IN ('information_schema' , 'mysql', 'performance_schema', 'sys') - GROUP BY S.SCHEMA_NAME - ORDER BY db_name ASC;`; - - pool - .query(query) - .then((databases) => { - const dbList: dbDetails[] = []; - - for (let i = 0; i < databases[0].length; i++) { - const data = databases[0][i]; - const { db_name } = data; - if ( - db_name !== 'postgres' && - db_name !== 'template0' && - db_name !== 'template1' - ) { - data.db_type = dbType; - dbList.push(data); + const dbList: dbDetails[] = []; + + if (pool) { + query = ` + SELECT + S.SCHEMA_NAME db_name, + ROUND(SUM(data_length + index_length) / 1024, 1) db_size + FROM + INFORMATION_SCHEMA.SCHEMATA S + LEFT OUTER JOIN + INFORMATION_SCHEMA.TABLES T ON S.SCHEMA_NAME = T.TABLE_SCHEMA + WHERE + S.SCHEMA_NAME NOT IN ('information_schema' , 'mysql', 'performance_schema', 'sys') + GROUP BY S.SCHEMA_NAME + ORDER BY db_name ASC;`; + + pool + .query(query) + .then((databases) => { + for (let i = 0; i < databases[0].length; i++) { + const data = databases[0][i]; + const { db_name } = data; + if ( + db_name !== 'postgres' && + db_name !== 'template0' && + db_name !== 'template1' + ) { + data.db_type = dbType; + dbList.push(data); + } } - } - logger("MySQL 'getDBNames' resolved.", LogType.SUCCESS); - // resolve with array of db names + logger("MySQL 'getDBNames' resolved.", LogType.SUCCESS); + // resolve with array of db names - resolve(dbList); - }) - .catch((err) => { - reject(err); - }); + resolve(dbList); + }) + .catch((err) => { + reject(err); + }); + } else { + resolve(dbList); + } } }); }; -// function that gets all tablenames and their columns from current schema +//JUNAID +//this runs when you click on a specific loaded db from the list. +//this queries the db and gets all the info const getDBLists = function ( dbType: DBType, dbName: string @@ -251,41 +260,42 @@ const getDBLists = function ( if (dbType === DBType.Postgres) pool = pg_pool; if (dbType === DBType.RDSPostgres) pool = rds_pg_pool; - query = `SELECT - table_catalog, - table_schema, - table_name, - is_insertable_into - FROM information_schema.tables - WHERE table_schema = 'public' or table_schema = 'base' - ORDER BY table_name;`; - - pool - .query(query) - .then((tables) => { - for (let i = 0; i < tables.rows.length; i++) { - tableList.push(tables.rows[i]); - promiseArray.push( - getColumnObjects(tables.rows[i].table_name, dbType) - ); - } - - Promise.all(promiseArray) - .then((columnInfo) => { - for (let i = 0; i < columnInfo.length; i++) { - tableList[i].columns = columnInfo[i]; - } + // if (pool) { + query = `SELECT + table_catalog, + table_schema, + table_name, + is_insertable_into + FROM information_schema.tables + WHERE table_schema = 'public' or table_schema = 'base' + ORDER BY table_name;`; + pool + .query(query) + .then((tables) => { + for (let i = 0; i < tables.rows.length; i++) { + tableList.push(tables.rows[i]); + promiseArray.push( + getColumnObjects(tables.rows[i].table_name, dbType) + ); + } - logger("PG 'getDBLists' resolved.", LogType.SUCCESS); - resolve(tableList); - }) - .catch((err) => { - reject(err); - }); - }) - .catch((err) => { - reject(err); - }); + Promise.all(promiseArray) + .then((columnInfo) => { + for (let i = 0; i < columnInfo.length; i++) { + tableList[i].columns = columnInfo[i]; + } + + logger("PG 'getDBLists' resolved.", LogType.SUCCESS); + resolve(tableList); + }) + .catch((err) => { + reject(err); + }); + }) + .catch((err) => { + reject(err); + }); + // } } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { // Notice that TABLE_CATALOG is set to table_schema // And that TABLE_SCHEMA is set to table_catalog @@ -295,45 +305,46 @@ const getDBLists = function ( if (dbType === DBType.MySQL) pool = msql_pool; if (dbType === DBType.RDSMySQL) pool = rds_msql_pool; - query = `SELECT - TABLE_CATALOG as table_schema, - TABLE_SCHEMA as table_catalog, - TABLE_NAME as table_name - FROM information_schema.tables - WHERE TABLE_SCHEMA NOT IN("information_schema", "performance_schema", "mysql") - AND TABLE_SCHEMA = "${dbName}" - ORDER BY table_name;`; - - pool - .query(query) - .then((tables) => { - for (let i = 0; i < tables[0].length; i++) { - tableList.push(tables[0][i]); - - // Sys returns way too much stuff idk - if (tableList[i].table_schema !== 'sys') { - promiseArray.push( - getColumnObjects(tableList[i].table_name, dbType) - ); - } - } - - Promise.all(promiseArray) - .then((columnInfo) => { - for (let i = 0; i < columnInfo.length; i++) { - tableList[i].columns = columnInfo[i]; + // if (pool) { + query = `SELECT + TABLE_CATALOG as table_schema, + TABLE_SCHEMA as table_catalog, + TABLE_NAME as table_name + FROM information_schema.tables + WHERE TABLE_SCHEMA NOT IN("information_schema", "performance_schema", "mysql") + AND TABLE_SCHEMA = "${dbName}" + ORDER BY table_name;`; + + pool + .query(query) + .then((tables) => { + for (let i = 0; i < tables[0].length; i++) { + tableList.push(tables[0][i]); + + // Sys returns way too much stuff idk + if (tableList[i].table_schema !== 'sys') { + promiseArray.push( + getColumnObjects(tableList[i].table_name, dbType) + ); } - - logger("MySQL 'getDBLists' resolved.", LogType.SUCCESS); - resolve(tableList); - }) - .catch((err) => { - reject(err); - }); - }) - .catch((err) => { - reject(err); - }); + } + Promise.all(promiseArray) + .then((columnInfo) => { + for (let i = 0; i < columnInfo.length; i++) { + tableList[i].columns = columnInfo[i]; + } + + logger("MySQL 'getDBLists' resolved.", LogType.SUCCESS); + resolve(tableList); + }) + .catch((err) => { + reject(err); + }); + }) + .catch((err) => { + reject(err); + }); + // } } }); }; @@ -424,51 +435,50 @@ const DBFunctions: DBFunctions = { async setBaseConnections() { const PG_Cred = docConfig.getCredentials(DBType.Postgres); const MSQL_Cred = docConfig.getCredentials(DBType.MySQL); - const RDS_PG_Cred = docConfig.getCredentials(DBType.RDSPostgres); - const RDS_MSQL_Cred = docConfig.getCredentials(DBType.RDSMySQL); - - // this is a dum solution but it needs to be passed in as password into the pool - // and i would rather do it here than in the documentsconfig file - this.curRDS_MSQL_DB = { - host: RDS_MSQL_Cred.host, - user: RDS_MSQL_Cred.user, - password: RDS_MSQL_Cred.pass, - port: RDS_MSQL_Cred.port, - }; - - this.curRDS_PG_DB = { - host: RDS_PG_Cred.host, - user: RDS_PG_Cred.user, - password: RDS_PG_Cred.pass, - port: RDS_PG_Cred.port, - }; - - // RDS PG POOL - await RDS_PG_DBConnect(this.curRDS_PG_DB); - - // RDS MSQL POOL - await RDS_MSQL_DBConnect(this.curRDS_MSQL_DB); + this.curRDS_PG_DB = docConfig.getCredentials(DBType.RDSPostgres); + this.curRDS_MSQL_DB = docConfig.getCredentials(DBType.RDSMySQL); + + if ( + this.curRDS_PG_DB.user && + this.curRDS_PG_DB.password && + this.curRDS_PG_DB.host + ) { + // RDS PG POOL + await RDS_PG_DBConnect(this.curRDS_PG_DB); + } + + if ( + this.curRDS_MSQL_DB.user && + this.curRDS_MSQL_DB.password && + this.curRDS_MSQL_DB.host + ) { + // RDS MSQL POOL + await RDS_MSQL_DBConnect(this.curRDS_MSQL_DB); + } // URI Format: postgres://username:password@hostname:port/databasename // Note User must have a 'postgres'role set-up prior to initializing this connection. https://www.postgresql.org/docs/13/database-roles.html // ^Unknown if this rule is still true + if (PG_Cred.user && PG_Cred.pass) { + // LOCAL PG POOL + this.pg_uri = `postgres://${PG_Cred.user}:${PG_Cred.pass}@localhost:${PG_Cred.port}/`; + await PG_DBConnect(this.pg_uri, this.curPG_DB); + } - // LOCAL PG POOL - this.pg_uri = `postgres://${PG_Cred.user}:${PG_Cred.pass}@localhost:${PG_Cred.port}/`; - await PG_DBConnect(this.pg_uri, this.curPG_DB); - - // LOCAL MSQL POOL - await MSQL_DBConnect({ - host: `localhost`, - port: MSQL_Cred.port, - user: MSQL_Cred.user, - password: MSQL_Cred.pass, - database: this.curMSQL_DB, - waitForConnections: true, - connectionLimit: 10, - queueLimit: 0, - multipleStatements: true, - }); + if (MSQL_Cred.user) { + // LOCAL MSQL POOL + await MSQL_DBConnect({ + host: `localhost`, + port: MSQL_Cred.port, + user: MSQL_Cred.user, + password: MSQL_Cred.pass, + database: this.curMSQL_DB, + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, + multipleStatements: true, + }); + } }, // RUN ANY QUERY - function that will run query on database that is passed in. @@ -485,9 +495,7 @@ const DBFunctions: DBFunctions = { // Checking if database type (dbType) is MySQL if (dbType === DBType.MySQL) { return new Promise((resolve, reject) => { - console.log(this.curMSQL_DB, 'are we here twoice?'); if (this.curMSQL_DB) { - console.log('here twice too?'); // MySQL requires you to use the USE query in order to connect to a db and run msql_pool .query(`USE ${this.curMSQL_DB}; ${text}`, params, dbType) @@ -508,7 +516,6 @@ const DBFunctions: DBFunctions = { }); }); } else { - console.log('are we hitting else>?'); msql_pool // MySQL requires you to use the USE query in order to connect to a db and run .query(text, params, dbType) From a39e259e4b19fed9abceb137641a18dadaedb28e Mon Sep 17 00:00:00 2001 From: Junaid Ahmed Date: Mon, 3 Apr 2023 15:39:40 -0400 Subject: [PATCH 10/10] chase and junaid refactored models page, changed getLists from promise chaning to use try catch blocks and aync await, created object to check which databases the user was trying to login with, so that only those databases will connect, and that if youre missing any of the logins, the code still works and will just log you in to whichever dbs you wanted to log into. --- backend/channels.ts | 22 +++- backend/models.ts | 308 ++++++++++++++++++++------------------------ 2 files changed, 155 insertions(+), 175 deletions(-) diff --git a/backend/channels.ts b/backend/channels.ts index 583581a6..0e115f04 100644 --- a/backend/channels.ts +++ b/backend/channels.ts @@ -66,7 +66,10 @@ ipcMain.handle('get-config', async (event, configObj) => { }); // Listen for request from front-end and send back the DB List upon request -ipcMain.on('return-db-list', (event, dbType: DBType = DBType.Postgres) => { +//JUNAID AND CHASE +//removed the parameters because it doesnt seem like they do anything here, and it prevents the other databses from rendering on the list if pg is passed in. +// ipcMain.on('return-db-list', (event, dbType: DBType = DBType.Postgres) => { +ipcMain.on('return-db-list', (event) => { logger( "Received 'return-db-list' (Note: No Async being sent here)", LogType.RECEIVE @@ -74,7 +77,10 @@ ipcMain.on('return-db-list', (event, dbType: DBType = DBType.Postgres) => { db.setBaseConnections() .then(() => { - db.getLists('', dbType) + //JUNAID AND CHASE + //removed the parameters because it doesnt seem like they do anything here, and it prevents the other databses from rendering on the list if pg is passed in. + // db.getLists('', dbType) + db.getLists() .then((data: DBList) => { event.sender.send('db-lists', data); logger("Sent 'db-lists' from 'return-db-list'", LogType.SEND); @@ -440,7 +446,8 @@ interface dummyDataRequestPayload { rows: number; } -ipcMain.handle( // generate dummy data +ipcMain.handle( + // generate dummy data 'generate-dummy-data', async (event, data: dummyDataRequestPayload, dbType: DBType) => { logger("Received 'generate-dummy-data'", LogType.RECEIVE); @@ -453,11 +460,14 @@ ipcMain.handle( // generate dummy data }; try { // console.log('data in generate-dummy-data', data); // gets here fine - + // Retrieves the Primary Keys and Foreign Keys for all the tables - const tableInfo: ColumnObj[] = await db.getTableInfo(data.tableName, dbType); // passed in dbType to second argument + const tableInfo: ColumnObj[] = await db.getTableInfo( + data.tableName, + dbType + ); // passed in dbType to second argument // console.log('tableInfo in generate-dummy-data', tableInfo); // working - + // generate dummy data const dummyArray: DummyRecords = await generateDummyData( tableInfo, diff --git a/backend/models.ts b/backend/models.ts index 072802e4..0024c340 100644 --- a/backend/models.ts +++ b/backend/models.ts @@ -182,6 +182,7 @@ const getDBNames = function (dbType: DBType): Promise { reject(err); }); } else { + console.log(dbList, 'in pg'); resolve(dbList); } } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { @@ -237,6 +238,7 @@ const getDBNames = function (dbType: DBType): Promise { reject(err); }); } else { + console.log(dbList, 'in mysql'); resolve(dbList); } } @@ -261,7 +263,7 @@ const getDBLists = function ( if (dbType === DBType.RDSPostgres) pool = rds_pg_pool; // if (pool) { - query = `SELECT + query = `SELECT table_catalog, table_schema, table_name, @@ -269,32 +271,32 @@ const getDBLists = function ( FROM information_schema.tables WHERE table_schema = 'public' or table_schema = 'base' ORDER BY table_name;`; - pool - .query(query) - .then((tables) => { - for (let i = 0; i < tables.rows.length; i++) { - tableList.push(tables.rows[i]); - promiseArray.push( - getColumnObjects(tables.rows[i].table_name, dbType) - ); - } + pool + .query(query) + .then((tables) => { + for (let i = 0; i < tables.rows.length; i++) { + tableList.push(tables.rows[i]); + promiseArray.push( + getColumnObjects(tables.rows[i].table_name, dbType) + ); + } - Promise.all(promiseArray) - .then((columnInfo) => { - for (let i = 0; i < columnInfo.length; i++) { - tableList[i].columns = columnInfo[i]; - } - - logger("PG 'getDBLists' resolved.", LogType.SUCCESS); - resolve(tableList); - }) - .catch((err) => { - reject(err); - }); - }) - .catch((err) => { - reject(err); - }); + Promise.all(promiseArray) + .then((columnInfo) => { + for (let i = 0; i < columnInfo.length; i++) { + tableList[i].columns = columnInfo[i]; + } + + logger("PG 'getDBLists' resolved.", LogType.SUCCESS); + resolve(tableList); + }) + .catch((err) => { + reject(err); + }); + }) + .catch((err) => { + reject(err); + }); // } } else if (dbType === DBType.MySQL || dbType === DBType.RDSMySQL) { // Notice that TABLE_CATALOG is set to table_schema @@ -306,7 +308,7 @@ const getDBLists = function ( if (dbType === DBType.RDSMySQL) pool = rds_msql_pool; // if (pool) { - query = `SELECT + query = `SELECT TABLE_CATALOG as table_schema, TABLE_SCHEMA as table_catalog, TABLE_NAME as table_name @@ -315,35 +317,35 @@ const getDBLists = function ( AND TABLE_SCHEMA = "${dbName}" ORDER BY table_name;`; - pool - .query(query) - .then((tables) => { - for (let i = 0; i < tables[0].length; i++) { - tableList.push(tables[0][i]); - - // Sys returns way too much stuff idk - if (tableList[i].table_schema !== 'sys') { - promiseArray.push( - getColumnObjects(tableList[i].table_name, dbType) - ); - } + pool + .query(query) + .then((tables) => { + for (let i = 0; i < tables[0].length; i++) { + tableList.push(tables[0][i]); + + // Sys returns way too much stuff idk + if (tableList[i].table_schema !== 'sys') { + promiseArray.push( + getColumnObjects(tableList[i].table_name, dbType) + ); } - Promise.all(promiseArray) - .then((columnInfo) => { - for (let i = 0; i < columnInfo.length; i++) { - tableList[i].columns = columnInfo[i]; - } - - logger("MySQL 'getDBLists' resolved.", LogType.SUCCESS); - resolve(tableList); - }) - .catch((err) => { - reject(err); - }); - }) - .catch((err) => { - reject(err); - }); + } + Promise.all(promiseArray) + .then((columnInfo) => { + for (let i = 0; i < columnInfo.length; i++) { + tableList[i].columns = columnInfo[i]; + } + + logger("MySQL 'getDBLists' resolved.", LogType.SUCCESS); + resolve(tableList); + }) + .catch((err) => { + reject(err); + }); + }) + .catch((err) => { + reject(err); + }); // } } }); @@ -411,6 +413,13 @@ interface DBFunctions { curMSQL_DB: string; curRDS_MSQL_DB: any; curRDS_PG_DB: any; + dbsInputted: { + pg: boolean; + msql: boolean; + rds_pg: boolean; + rds_msql: boolean; + }; + setBaseConnections: () => Promise; query: ( text: string, @@ -429,7 +438,12 @@ const DBFunctions: DBFunctions = { curMSQL_DB: '', curRDS_MSQL_DB: '', curRDS_PG_DB: '', - + dbsInputted: { + pg: false, + msql: false, + rds_pg: false, + rds_msql: false, + }, // JUNAID // start the initial connecttion for all four of our databases. want to extract to a seperate file later on, but not right now. will be a little tricky due to the pool variables that we use throughout the page async setBaseConnections() { @@ -443,6 +457,7 @@ const DBFunctions: DBFunctions = { this.curRDS_PG_DB.password && this.curRDS_PG_DB.host ) { + this.dbsInputted.rds_pg = true; // RDS PG POOL await RDS_PG_DBConnect(this.curRDS_PG_DB); } @@ -453,6 +468,7 @@ const DBFunctions: DBFunctions = { this.curRDS_MSQL_DB.host ) { // RDS MSQL POOL + this.dbsInputted.rds_msql = true; await RDS_MSQL_DBConnect(this.curRDS_MSQL_DB); } @@ -460,12 +476,14 @@ const DBFunctions: DBFunctions = { // Note User must have a 'postgres'role set-up prior to initializing this connection. https://www.postgresql.org/docs/13/database-roles.html // ^Unknown if this rule is still true if (PG_Cred.user && PG_Cred.pass) { + this.dbsInputted.pg = true; // LOCAL PG POOL this.pg_uri = `postgres://${PG_Cred.user}:${PG_Cred.pass}@localhost:${PG_Cred.port}/`; await PG_DBConnect(this.pg_uri, this.curPG_DB); } if (MSQL_Cred.user) { + this.dbsInputted.msql = true; // LOCAL MSQL POOL await MSQL_DBConnect({ host: `localhost`, @@ -573,121 +591,73 @@ const DBFunctions: DBFunctions = { // databaseList: { db_name: 'name', db_size: '1000kB' } // tableList: { table_name: 'name', data_type: 'type', columns: [ colObj ], ...etc. } // } + //JUNAID // this seems to be the first function that runs when electron is launched - getLists(dbName: string = '', dbType?: DBType): Promise { - return new Promise((resolve, reject) => { - console.log('in getLists', ' db => ', dbName, ' dbType -> ', dbType); - const listObj: DBList = { - databaseConnected: [false, false, false, false], - databaseList: [], - tableList: [], // current database's tables - }; - // Get initial postgres dbs - getDBNames(DBType.Postgres) - .then((pgdata) => { - const pgDBList = pgdata; - listObj.databaseConnected[0] = true; - // Get MySQL DBs - getDBNames(DBType.MySQL) - .then((msdata) => { - const msqlDBList = msdata; - listObj.databaseConnected[1] = true; - logger('Got DB Names for both PG and MySQL!', LogType.SUCCESS); - getDBNames(DBType.RDSPostgres).then((rdspgdata) => { - const rdspgDBList = rdspgdata; - listObj.databaseConnected[2] = true; - getDBNames(DBType.RDSMySQL) - .then((rdsmsqldata) => { - const rdsmsqlDBList = rdsmsqldata; - listObj.databaseConnected[3] = true; - listObj.databaseList = [ - ...pgDBList, - ...msqlDBList, - ...rdspgDBList, - ...rdsmsqlDBList, - ]; - }) - .finally(() => { - if (dbType) { - // console.log('dbType is defined') - getDBLists(dbType, dbName) // dbLists returning empty array - DBType is not defined - .then((data) => { - logger( - `RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, - LogType.SUCCESS - ); - listObj.tableList = data; - resolve(listObj); - }) - .catch((err) => { - logger( - `Error getting tableList details: ${err.message}`, - LogType.ERROR - ); - }); - } else { - // console.log('dbType is not defined') - logger( - 'RESOLVING DB DETAILS: Only DB Names', - LogType.SUCCESS - ); - resolve(listObj); - } - }); - }); - }) - .catch((err) => { - // MySQL fails... Just get PG! - logger( - "Couldn't connect to MySQL. Sending only PG Data!", - LogType.ERROR - ); - listObj.databaseList = pgDBList; - }); - }) - .catch((err) => { - // If PG fails, try just sending MySQL. - logger( - "Couldn't connect to PG. Attempting to connect to MySQL instead!", - LogType.ERROR - ); - // Get MySQL DBs - getDBNames(DBType.MySQL) - .then((msdata) => { - listObj.databaseList = msdata; - - // This is not in a .finally block because if getting MySQL data fails then nothing returns. - if (dbType) { - getDBLists(dbType, dbName) - .then((data) => { - logger( - `RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, - LogType.SUCCESS - ); - listObj.tableList = data; - resolve(listObj); - }) - .catch((err) => { - logger( - `Error getting tableList details: ${err.message}`, - LogType.ERROR - ); - }); - } else { - logger('RESOLVING DB DETAILS: Only DB Names', LogType.SUCCESS); - resolve(listObj); - } - }) - .catch((err) => { - logger( - `Could not connect to either PG or MySQL: ${err.message}`, - LogType.ERROR - ); - throw err; - }); - }); - }); + async getLists(dbName: string = '', dbType?: DBType): Promise { + + const listObj: DBList = { + databaseConnected: [false, false, false, false], + databaseList: [], + tableList: [] + }; + + if (this.dbsInputted.pg) { + try { + const pgDBList = await getDBNames(DBType.Postgres); + listObj.databaseConnected[0] = true; + listObj.databaseList = [...listObj.databaseList, ...pgDBList]; + } catch (error) { + logger('COULDNT GET NAMES FROM LOCAL PG', LogType.ERROR); + } + } + + if (this.dbsInputted.msql) { + try { + const msqlDBList = await getDBNames(DBType.MySQL); + listObj.databaseConnected[1] = true; + listObj.databaseList = [...listObj.databaseList, ...msqlDBList]; + } catch (error) { + logger('COULDNT GET NAMES FROM LOCAL MSQL', LogType.ERROR); + } + } + + if (this.dbsInputted.rds_msql) { + try { + const RDSmsqlDBList = await getDBNames(DBType.RDSMySQL); + listObj.databaseConnected[2] = true; + listObj.databaseList = [...listObj.databaseList, ...RDSmsqlDBList]; + } catch (error) { + logger('COULDNT GET NAMES FROM RDS MSQL', LogType.ERROR); + } + } + + if (this.dbsInputted.rds_pg) { + try { + const RDSpgDBList = await getDBNames(DBType.RDSPostgres); + listObj.databaseConnected[3] = true; + listObj.databaseList = [...listObj.databaseList, ...RDSpgDBList]; + } catch (error) { + logger('COULDNT GET NAMES FROM RDS PG', LogType.ERROR); + } + } + + if (dbType) { + try { + const listData = await getDBLists(dbType, dbName); + logger( + `RESOLVING DB DETAILS: Fetched DB names along with Table List for DBType: ${dbType} and DB: ${dbName}`, + LogType.SUCCESS + ); + listObj.tableList = listData; + } catch (error) { + logger( + `COULNT GET DATABASE LIST FOR ${dbType} ${dbName} DATABASE`, + LogType.ERROR + ); + } + } + return listObj; }, // Returns an array of columnObj given a tableName