Skip to content

Commit

Permalink
Merge pull request #1 from oslabs-beta/funcDelete
Browse files Browse the repository at this point in the history
Func delete - delete and save bugs re mySQL + pg
  • Loading branch information
nathanhchong authored Jun 22, 2023
2 parents 10b2839 + 6e50ce7 commit 7493010
Show file tree
Hide file tree
Showing 18 changed files with 477 additions and 21,869 deletions.
3 changes: 3 additions & 0 deletions backend/BE_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ export interface DBFunctions {
setBaseConnections: () => Promise<dbsInputted>;
query: (text: string, params: (string | number)[], dbType: DBType) => void;
connectToDB: (db: string, dbType?: DBType) => Promise<void>;
////////eric////////
closeTheDB: (db: string, dbType?: DBType) => Promise<void>;
////////////////////
getLists: (dbName: string, dbType?: DBType) => Promise<DBList>;
getTableInfo: (tableName: string, dbType: DBType) => Promise<ColumnObj[]>;
getDBNames: (dbType: DBType) => Promise<dbDetails[]>;
Expand Down
39 changes: 29 additions & 10 deletions backend/DummyD/dummyDataMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,21 @@ const generateDataByType = (columnObj: ColumnObj): string | number => {
case 'character varying':
// defaulting length to 3 because faker.lorem defaults to a length of 3 if no length is specified

length = columnObj.character_maximum_length && columnObj.character_maximum_length < 3
length = columnObj.character_maximum_length && columnObj.character_maximum_length > 3
? Math.floor(Math.random() * columnObj.character_maximum_length)
: 3;
return '\''.concat(faker.random.alphaNumeric(length)).concat('\'');
/////////////////////////////////////////eric for mySQL////////////////////////////////////////////////////////////////////
case 'varchar':
// defaulting length to 3 because faker.lorem defaults to a length of 3 if no length is specified

length = columnObj.character_maximum_length && columnObj.character_maximum_length > 3
? Math.floor(Math.random() * columnObj.character_maximum_length)
: 3;
return '\''.concat(faker.random.alphaNumeric(length)).concat('\'');
case 'int':
return faker.random.number({ min: -2147483648, max: 2147483647 });
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
case 'date': {
// generating a random date between 1500 and 2020
const year = getRandomInt(1500, 2020).toString();
Expand Down Expand Up @@ -77,7 +88,12 @@ const generateDummyData: GenerateDummyData = async (tableInfo: ColumnObj[], numR
for(let i = 0; i < tableInfo.length; i++) {
columnNames.push(tableInfo[i].column_name);
}

console.log('columnNames=======================ericCheck========================ericCheck========================columnNames', columnNames);
console.log('ericCheck=======================ericCheck========================ericCheck========================ericCheck');
console.log('tableInfo=======================ericCheck========================ericCheck========================tableInfo', tableInfo);
console.log('ericCheck=======================ericCheck========================ericCheck========================ericCheck');
console.log('numRows=======================ericCheck========================ericCheck========================numRows', numRows);
console.log('ericCheck=======================ericCheck========================ericCheck========================ericCheck');
const dummyRecords: DummyRecords = [columnNames];

// generate dummy records for each row
Expand All @@ -86,14 +102,17 @@ const generateDummyData: GenerateDummyData = async (tableInfo: ColumnObj[], numR
// at each row, check the columns of the table and generate dummy data accordingly
for (let j = 0; j < tableInfo.length; j += 1) {
// if column has no foreign key constraint, then generate dummy data based on data type
if (
tableInfo[j].constraint_type !== 'FOREIGN KEY'
if (tableInfo[j].constraint_type !== 'FOREIGN KEY'){
// && tableInfo[j].constraint_type !== 'PRIMARY KEY'
) row.push(generateDataByType(tableInfo[j]));
console.log('ericCheckericCheckericCheckericCheckericCheckericCheckericCheckericCheckericCheckericCheckericCheckericCheck========================ericCheck========================ericCheck');
row.push(generateDataByType(tableInfo[j]))
console.log('row=======================ericCheck========================ericCheck========================rowrowrowrowrowrow', row);
console.log('ericCheck=======================ericCheck========================ericCheck========================ericCheck');
}

// if there is a foreign key constraint, grab random key from foreign table
else if (tableInfo[j].constraint_type === 'FOREIGN KEY') {
try {
// try {
const foreignColumn = tableInfo[j].foreign_column;
const foreignTable = tableInfo[j].foreign_table;
const getForeignKeyQuery = `
Expand All @@ -111,10 +130,10 @@ const generateDummyData: GenerateDummyData = async (tableInfo: ColumnObj[], numR
logger('There was an error while retrieving a valid foreign key while generating dummy data.', LogType.ERROR);
throw new Error('There was an error while retrieving a valid foreign key.');
}
}
catch(err) {
throw err;
}
// }
// catch(err) {
// throw err;
// }
}
}
dummyRecords.push(row);
Expand Down
195 changes: 171 additions & 24 deletions backend/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import generateDummyData from './DummyD/dummyDataMain';
import { ColumnObj, DBList, DummyRecords, DBType, LogType } from './BE_types';
import backendObjToQuery from './ertable-functions';
import logger from './Logging/masterlog';
import { Integer } from 'type-fest';

const db = require('./models');
const docConfig = require('./_documentsConfig');
Expand Down Expand Up @@ -165,6 +166,8 @@ ipcMain.handle(
}
);



// Deletes the DB that is passed from the front end and returns an updated DB List
ipcMain.handle(
'drop-db',
Expand All @@ -177,18 +180,44 @@ ipcMain.handle(
logger("Received 'drop-db'", LogType.RECEIVE);

event.sender.send('async-started');

try {
// db.setBaseConnections()
// .then(() => {

// db.getLists()
// .then((data: DBList) => {
// event.sender.send('db-lists', data);
// logger("888888888888888888");
// })
// });

// if deleting currently connected db, disconnect from db
if (currDB) await db.connectToDB('', dbType);
// if (currDB) await db.connectToDB('', dbType);


// drop db
// ////////eric////////
await db.connectToDB('', dbType);
if(dbType === DBType.Postgres){
await db.query(`UPDATE pg_database SET datallowconn = 'false' WHERE datname = '${dbName}'`, null, dbType);
await db.query(`
SELECT pid, pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = '${dbName}' AND pid <> pg_backend_pid();
`, null, dbType);
// await db.closeTheDB(dbName, dbType);
console.log('777777777777777777777777777777777777777777777');
}
const dropDBScript = dropDBFunc(dbName, dbType);
await db.query(dropDBScript, null, dbType);

// send updated db info
const dbsAndTables: DBList = await db.getLists(dbName, dbType);
event.sender.send('db-lists', dbsAndTables);
logger("Sent 'db-lists' from 'drop-db'", LogType.SEND);
} catch (e: any) {
logger(`888888888888888888888888888888888: ${e.message}`, LogType.WARNING);
throw new Error('888888888888888888888888888888888');
} finally {
event.sender.send('async-complete');
}
Expand Down Expand Up @@ -330,6 +359,7 @@ interface QueryPayload {
targetDb: string;
sqlString: string;
selectedDb: string;
runQueryNumber: number;
}

// Run query passed from the front-end, and send back an updated DB List
Expand All @@ -342,48 +372,153 @@ ipcMain.handle(
'run-query',
async (
event,
{ targetDb, sqlString, selectedDb }: QueryPayload,
{ targetDb, sqlString, selectedDb, runQueryNumber}: QueryPayload,
dbType: DBType
) => {
logger(
"Received 'run-query'",
LogType.RECEIVE,
`selectedDb: ${selectedDb} and dbType: ${dbType}`
`selectedDb: ${selectedDb} and dbType: ${dbType} and runQueryNumber: ${runQueryNumber}`
);
event.sender.send('async-started');
const arr: any[] = [];
const numberOfSample: number = runQueryNumber;
let totalSampleTime: number = 0;
let minmumSampleTime: number = 0;
let maximumSampleTime: number = 0;
let averageSampleTime: number = 0;

function parseExplainExplanation(explain) {
const regex = /actual time=(\d+\.\d+)\.\.(\d+\.\d+) rows=\d+ loops=(\d+)/g;
const matches: any[] = Array.from(explain.matchAll(regex));
let result: number = 0;

for(let i = 0; i < matches.length; i+=1){
result += (parseFloat(matches[i][2]) - parseFloat(matches[i][1])) * parseFloat(matches[i][3]);
}
return result;
}
///// /////////// /////////// /////////// ///////////

try {
let error: string | undefined;
// connect to db to run query

if (selectedDb !== targetDb) await db.connectToDB(targetDb, dbType);

// Run Explain
// Run Explain
let explainResults;
try {
if (dbType === DBType.Postgres) {
const results = await db.query(
explainQuery(sqlString, dbType),
null,
dbType
);
// console.log(LogType.WARNING, results);
explainResults = results[1].rows;
} else if (dbType === DBType.MySQL) {
const results = await db.query(
explainQuery(sqlString, dbType),
null,
dbType
);
explainResults = results[0][0];
// console.log('mysql explain results', explainResults);

// console.log(LogType.WARNING, results);
for(let i = 0; i < numberOfSample; i++){
if (dbType === DBType.Postgres) {
const results = await db.query(
explainQuery(sqlString, dbType),
null,
dbType
);

console.log('ericCheck------------------------------------------------------------------ericCheck');
console.log('postgerSQL_results-----------------------------------------------------------------postgerSQL_results', results);
console.log('postgerSQL_results[1].rows-----------------------------------------------------------------postgerSQL_results[1].rows', results[1].rows);
console.log('postgerSQL_results[1].rows[0]["QUERY PLAN"][0]-----------------------------------------------------------------postgerSQL_results[1].rows[0]["QUERY PLAN"][0]', results[1].rows[0]["QUERY PLAN"][0]);

explainResults = results[1].rows;
const eachSampleTime: any = results[1].rows[0]["QUERY PLAN"][0]['Planning Time'] + results[1].rows[0]["QUERY PLAN"][0]['Execution Time'];
arr.push(eachSampleTime);
totalSampleTime += eachSampleTime;

} else if (dbType === DBType.MySQL) {
const results = await db.query(
explainQuery(sqlString, dbType),
null,
dbType
);
console.log('ericCheck------------------------------------------------------------------ericCheck');
console.log('mySQL_results-----------------------------------------------------------------mySQL_results', results);
console.log('results[0][0]-----------------------------------------------------------------results[0][0]', results[0][0]);

const eachSampleTime: any = parseExplainExplanation(results[0][0].EXPLAIN);
arr.push(eachSampleTime);
totalSampleTime += eachSampleTime;
console.log('ericCheck------------------------------------------------------------------ericCheck');
console.log('arr-------------------------------------------------------------------arr', arr);


// //////////not real result just try to get rid of bugs first///////////////
explainResults = {
Plan: {
'Node Type': 'Seq Scan',
'Parallel Aware': false,
'Async Capable': false,
'Relation Name': 'newtable1',
Schema: 'public',
Alias: 'newtable1',
'Startup Cost': 0,
'Total Cost': 7,
'Plan Rows': 200,
'Plan Width': 132,
'Actual Startup Time': 0.015,
'Actual Total Time': 0.113,
'Actual Rows': 200,
'Actual Loops': 1,
Output: [ 'newcolumn1' ],
'Shared Hit Blocks': 5,
'Shared Read Blocks': 0,
'Shared Dirtied Blocks': 0,
'Shared Written Blocks': 0,
'Local Hit Blocks': 0,
'Local Read Blocks': 0,
'Local Dirtied Blocks': 0,
'Local Written Blocks': 0,
'Temp Read Blocks': 0,
'Temp Written Blocks': 0
},
Planning: {
'Shared Hit Blocks': 64,
'Shared Read Blocks': 0,
'Shared Dirtied Blocks': 0,
'Shared Written Blocks': 0,
'Local Hit Blocks': 0,
'Local Read Blocks': 0,
'Local Dirtied Blocks': 0,
'Local Written Blocks': 0,
'Temp Read Blocks': 0,
'Temp Written Blocks': 0
},
'Planning Time': 9999,
Triggers: [],
'Execution Time': 9999
};
// ////////////////////////////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////////////////////////////


// explainResults = results[0][0];
// console.log('mysql explain results', explainResults);

// console.log(LogType.WARNING, results);

}
}
console.log('ericCheck------------------------------------------------------------------ericCheck');
console.log('totalSampleTime------------------------------------------------------------------------------------------totalSampleTime', totalSampleTime);
// minmumSampleTime = Math.min(...arr);
// maximumSampleTime = Math.max(...arr);
// averageSampleTime = totalSampleTime/numberOfSample;
minmumSampleTime = Math.round(Math.min(...arr) * 10 ** 5) / 10 ** 5;
maximumSampleTime = Math.round(Math.max(...arr) * 10 ** 5) / 10 ** 5;
averageSampleTime = Math.round((totalSampleTime/numberOfSample) * 10 ** 5) / 10 ** 5;
totalSampleTime = Math.round(totalSampleTime * 10 ** 5) / 10 ** 5;
console.log('minmumSampleTime------------------------------------------------------------------------------------------minmumSampleTime', minmumSampleTime);
console.log('maximumSampleTime------------------------------------------------------------------------------------------maximumSampleTime', maximumSampleTime);
console.log('averageSampleTime------------------------------------------------------------------------------------------averageSampleTime', averageSampleTime);
} catch (e) {
error = `Failed to get Execution Plan. EXPLAIN might not support this query.`;
}


/////////// /////////// /////////// ///////////

// Run Query
let returnedRows;
try {
Expand All @@ -408,6 +543,11 @@ ipcMain.handle(
returnedRows,
explainResults,
error,
numberOfSample,
totalSampleTime,
minmumSampleTime,
maximumSampleTime,
averageSampleTime,
};
} finally {
// connect back to initialDb
Expand Down Expand Up @@ -494,13 +634,18 @@ ipcMain.handle(
dbType
); // passed in dbType to second argument
// console.log('tableInfo in generate-dummy-data', tableInfo); // working
// console.log('tableInfo==========================================================tableInfo', tableInfo);

// console.log('ericCheck=======================ericCheck========================ericCheck========================ericCheck');

// generate dummy data
const dummyArray: DummyRecords = await generateDummyData(
tableInfo,
data.rows
);
// console.log('dummyArray output: ', dummyArray)
// console.log('tableInfo==========================================================tableInfo', tableInfo);
// console.log('dummyArray==========================================================dummyArray', dummyArray);
// generate insert query string to insert dummy records
const columnsStringified = '('
.concat(dummyArray[0].join(', '))
Expand Down Expand Up @@ -571,13 +716,13 @@ ipcMain.handle(
try {
// create new empty db
await db.query(createDBFunc(newDbName, dbType), null, dbType);

// connect to initialized db
await db.connectToDB(newDbName, dbType);

// update DBList in the sidebar to show this new db
const dbsAndTableInfo: DBList = await db.getLists(newDbName, dbType);
event.sender.send('db-lists', dbsAndTableInfo);
///
logger("Sent 'db-lists' from 'initialize-db'", LogType.SEND);
} catch (e) {
const err = `Unsuccessful DB Creation for ${newDbName} in ${dbType} database`;
Expand Down Expand Up @@ -652,6 +797,8 @@ ipcMain.handle(
try {
// Generates query from backendObj
const query = backendObjToQuery(backendObj, dbType);
console.log('ipcMain-------------------------------------------------------------ipcMain', backendObj);
console.log('query=======================================================query', query);
// run sql command
await db.query('Begin;', null, dbType);
await db.query(query, null, dbType);
Expand Down
7 changes: 7 additions & 0 deletions backend/databaseConnections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ export default {
await pools.pg_pool.connect();
},

//////eric///////
PG_DBclose: async function (pg_uri: string, db: string) {

pools.pg_pool.end();
// pools.pg_pool = null;
},

MSQL_DBConnect: async function (MYSQL_CREDS: any) {
if (pools.msql_pool) await pools.msql_pool.end();
pools.msql_pool = await mysql.createPool({ ...MYSQL_CREDS });
Expand Down
Loading

0 comments on commit 7493010

Please sign in to comment.