Skip to content

Commit dcaefe6

Browse files
committed
maade changes to readme added GIF
2 parents 82f5d56 + ccc0235 commit dcaefe6

21 files changed

+195
-568
lines changed

.DS_Store

0 Bytes
Binary file not shown.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ node_modules/
55
build/
66
tmp/
77
temp/
8-
.cert
8+
.cert/

Contributors.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,25 @@
22

33
Below is a list of features and improvements to which you can contribute. If you have any additional ideas, please raise an issue or implement them as well!
44

5-
- Delete Table
6-
- Add a command to delete a table from the canvas, making sure to implement checks to maintain data integrity
75
- Logging needs a default settings list and direct reimport into live database.
8-
- The SQL code to import has been placed into the DB_Schemas folder along with SQL Schema dumps. Also, log setting functionality is currently limited to Postgres databases and the code needs to be expanded to query and display log setting info from MySQL databases.
6+
- The SQL code to import has been placed into the DB_Schemas folder along with SQL Schema dumps. Also, log setting functionality is currently limited to Postgres databases and the code needs to be expanded to query and display log setting info from MySQL databases.
97
- Db-schemas
108
- The schemas are saved under db_schemas and is saved in the server. Have a way to delete the schemas on the server from the front end. It would also be convenient to add these schemas to a list of existing schemas and be able to pull these schemas to display for the user to avoid having to make a new connection to the same database multiple times.
11-
- Expand compatibility with other SQL database such as Oracle SQL, Microsoft SQL, IBM Db2, etc.
9+
- Complete the integration of SQLite as an optional database and expand compatibility with other SQL database such as IBM Db2, etc.
1210
- Add additional themes and graphical options to canvas and tables
1311
- Live query feedback so users can see what their changes to the canvas look like as queries.
12+
<<<<<<< HEAD
13+
- As the ability to manipulate data has been recently added, there are not as many safe guards to prevent users from performing actions that are not allowed for some databases.
14+
- Limiting the data types to only those possible for the the database the user is currently working on.
15+
- Adding Account specific functionality and the ability to save data to your account.
16+
- TypeORM has been implemented to connect to multiple databases but can be modified to further universal database functions
17+
=======
1418
- Create login feature to save multiple databases to user account and be able to load multiple past databases.
19+
>>>>>>> dev
1520
1621
Known bugs/issues
1722

1823
- Undo function will not revert the state of the canvas to the point where it is empty.
24+
- Attempting to change the name of a column while adding a foreign key will result in the page crashing and going all white. Changing the column name is currently disabled.
25+
- When creating a new foreign key on a column, if you click submit while there is no table selected, the display area will shrink to a very small square in the top left corner of the page.
26+
- Exporting your query has been affected in the course of adding additional databases and needs to be reorganized

README.md

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121

2222
- Enhanced support for SQL databases with expanded options.
2323
- Introduction of visualized DATA tables for improved data analysis.
24-
- Full CRUD functionality enabling the addition, modification, and deletion of rows in DATA tables within the database.
25-
- Capability to remove tables as needed.
24+
- Robust CRUD functionality enabling the addition, modification, and deletion of rows in DATA tables within the database.
25+
- Capability to remove and add tables as needed.
2626
- Implementation of Google and GitHub OAuth log-ins for streamlined user authentication.
2727

2828

2929
### Use Cases
3030

31-
- Connecting to an existing remote PostgreSQL, MySQL, MicroSoftSQL, OracleSQL, and SQLite3 database
31+
- Connecting to an existing remote PostgreSQL, MySQL, MicroSoftSQL, OracleSQL databases
3232
- Renders an ER diagram for SCHEMA and DATA of the existing database and provides an interface for users to both modify existing tables and create new tables. A log of changes is stored, and at any point, the user can generate a query containing the changes, such that they are reflected in the existing database.
3333
- Uploading your database's SQL file
3434
- Renders an ER diagram for the provided SQL file (db dump) and provides an interface for a user to both modify existing tables and create new tables. Changes are converted into the corresponding queries, which the user can view and execute on their own database outside of dbSpy.
@@ -45,25 +45,26 @@
4545

4646
2. **ER Diagram Visuals:** Visualize the entity relationship diagram of a database with dynamic handle placement
4747

48-
3. **Table Relationship Visuals** Relationships of individual tables are easily identified when clicking on a table.
48+
3. **Table Relationship Visuals** Relationships of individual tables are easily identified when clicking on a table
4949

50-
4. **Schema Modification:** Easily modify a database's schema through a simple UI
50+
4. **Schema Modification:** Toggle between Schema and Data easily with a click of a button
51+
52+
5. **Data/Schema Modification:** Easily modify a database's schema or data through a simple UI
5153

5254
5. **Guided Database Building:** Create a new database from scratch using entity relationship diagrams to ensure the integrity of the database
5355

5456
6. **Database Undo/Redo:** Provides a history of edits for easier backtracking
5557

5658
7. **Query Generator:** Query generator generates executable SQL queries
5759

58-
8. **User Sessions:** Sign up/Log in securely with either Google OAuth or JWTs/Bcrypt
60+
8. **User Sessions:** Sign up/Log in securely with either Google/Github OAuth or JWTs/Bcrypt
5961

60-
9. **Save/Load:** Store and reload recent database sessions through your user account *-CURRENTLY UNDER UPDATE*
62+
9. **Save/Load:** Store and reload past database sessions through your user account *-CURRENTLY UNDER UPDATE*
6163

6264
10. **Dark Mode:** Visual settings to provide a more comfortable viewing experience in low-light environements
6365

6466
## <img src="images/Darkmode.png">
65-
## <img src="images/LandingPageDemo.gif">
66-
## <img src="images/MakingEditsDemo.gif">
67+
6768

6869
### Getting started
6970

@@ -94,6 +95,15 @@ PG_TEST_PW = <password string from PG_TEST_URL>
9495
## test user with saved schema to test save/load functionality
9596
TEST_USER_EMAIL = <email string>
9697
TEST_USER_PW = <password string>
98+
99+
GOOGLE_OAUTH_CLIENT_ID = <Google Oauth client id>
100+
GOOGLE_OAUTH_CLIENT_SECRET= <Google Oauth client id>
101+
GOOGLE_OAUTH_REDIRECT_URI = 'http://localhost:8080/display'
102+
103+
GITHUB_OAUTH_CLIENT_ID = <Github Oauth client id>
104+
GITHUB_OAUTH_CLIENT_SECRET= <Github Oauth client id>
105+
GITHUB_OAUTH_REDIRECT_URI = 'http://localhost:8080/display'
106+
97107
```
98108

99109
- Run the following below:
@@ -148,20 +158,26 @@ mkcert --version
148158
npm run cert:linux
149159
```
150160

161+
162+
163+
151164
---
152165

153166
# How to Use
154167

155168
### Connecting to an existing database
156169

157-
<img src="images/Existing%20Databse.png">
158-
159170
1. Click on the "Connect Database" button under the Action section on the left side of the page. This will open a sidebar on the right side of the page.
160171
2. Select the database type from the dropdown.
161172
3. Input your database URI information OR database connection credentials and click on "Connect".
162173
4. Once the connection to your database is established, the canvas will render and generate the tables and their relationships.
174+
* OracleSQL requires the download of the OCI - [here](https://www.oracle.com/cloud/free/)
175+
176+
177+
178+
## <img src="images/LandingPageDemo.gif">
179+
163180

164-
<img src="images/withDataButton.png">
165181

166182
### Uploading your database's SQL file
167183

@@ -175,30 +191,52 @@ npm run cert:linux
175191

176192
## Adding column(s) to a SCHEMA table or row(s) to a DATA table
177193

178-
1. To add a new column/row in a table, click on the add icon on the top right of the table node. This will render a new column/row in the table in edit mode. The changes made in DATA table will be updated in your database.
194+
1. To add a new column/row in a table, click on the add/plus icon on the top right of the table node.
195+
2. This will render a new column/row in the table in edit mode.
196+
3. Add in the data you would like in each column/row.
197+
4. Click on the confirm icon to save the column/row.
198+
5. The changes made in DATA table will be updated in your database.
199+
6. Click on the cancel icon to cancel the addition.
179200
<img src="images/Create%20tables.png">
180201
<img src="images/addRow.png">
181202

182-
### Editing an existing column to a SCHEMA table or row to a DATA table
203+
204+
### Editing an existing row of a DATA table
183205

184206
1. Click on the edit icon of the specific column that you want to edit.
185207
2. You can make changes to column fields based on the selections provided.
186208
3. Click on the save icon to keep your changes.
187209
4. Click on the cancel icon to cancel your changes.
188210

189-
## Deleting an column to a SCHEMA table or row to a DATA table
211+
### Deleting a column to a SCHEMA table or row of a DATA table
190212

191213
1. Click on the delete icon of the specific column that you want to delete.
192214
2. Click on the confirm icon to delete the column.
193215
3. Click on the cancel icon to cancel the deletion.
194216

217+
218+
## <img src="images/MakingEditsDemo.gif">
219+
220+
195221
### Adding a foreign key reference to a column
196222

197223
1. While editing a column, if setting Foreign Key (FK) to "true", the Foreign Key Reference sidebar will appear on the right side of the screen.
198224
2. In the Foreign Key Reference sidebar, use the displayed dropdowns to create references between tables.
199225
3. Click save or cancel to proceed.
200226
4. Click on the save icon to keep your changes or click on the cancel icon to cancel your changes.
201227

228+
### Adding a table to a database
229+
230+
1. When on the display page, click the 'Add Table' icon after you have either connected to a database or clicked 'Build Database'.
231+
2. Fill in the required information about the first column of your table along with a name.
232+
3. If you would like to include additional columns, click the 'Add Column' button in the top right corner.
233+
3. Click confirm to create your table.
234+
235+
### Deleting a table from a database
236+
237+
1. After you have either connected to a database or started a new database, the 'Delete Table' icon will appear on the left side of the display page
238+
2. This will open a pop out with a list of tables from the database.
239+
3. Select which table that you would like to have removed, and confirm to have it deleted.
202240

203241
### Navigating the canvas
204242

@@ -220,9 +258,9 @@ npm run cert:linux
220258
---
221259

222260
### Credits/Contributors
223-
- Yichung Chiu • [LinkedIn][Github]
224-
- Joseph Tejeda • [LinkedIn][Github]
225-
- Stephen Havig • [LinkedIn][Github]
261+
- Yichung Chiu • [LinkedIn](https://www.linkedin.com/in/yichung-chiu-b14a94272/)[Github](https://github.com/ychiu5896)
262+
- Joseph Tejeda • [LinkedIn](https://www.linkedin.com/in/atxjtejeda/)[Github](https://github.com/JosephTejeda)
263+
- Stephen Havig • [LinkedIn](https://www.linkedin.com/in/stephen-havig-199340145/)[Github](https://github.com/Stephen-Havig)
226264
- Das Kang • [LinkedIn](https://www.linkedin.com/in/das-kang/)[Github](https://github.com/dahae0309)
227265
- Alexander Tu • [LinkedIn](https://www.linkedin.com/in/atu816/)[Github](http://github.com/atu816)
228266
- Michael Costello • [LinkedIn](https://www.linkedin.com/in/mcostello-swe/)[Github](https://github.com/neighbor-peace)

server/controllers/helperFunctions/universal.helpers.ts

Lines changed: 42 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,12 @@ import { RequestHandler, Request, Response, NextFunction } from 'express';
22
import { DataSource } from 'typeorm';
33

44

5+
// HELPER FUNCTIONS FOR THE HELPER FUNCTIONS
56

67
const tableNameFormat = async (req: Request, dbDataSource: DataSource) => {
78
const { db_type, username } = req.session;
89
const { tableName } = req.body;
910

10-
// let newTableName = '';
11-
// if (tableName.substring(0, 7) === '.public') {
12-
// newTableName = tableName.slice(7)
13-
// } else {
14-
// newTableName = tableName
15-
// };
16-
1711
let tableNameFormat = '';
1812
switch (db_type) {
1913
case 'oracle':
@@ -194,7 +188,7 @@ export const updateRow: RequestHandler = async (req: Request, _res: Response, ne
194188

195189
await dbDataSource.destroy();
196190
console.log('Database has been disconnected');
197-
return dbUpdatedRow;
191+
return dbUpdatedRow;
198192

199193
} catch (err: unknown) {
200194
console.log('Error occurred in the updatedRow middleware: ', err);
@@ -209,49 +203,25 @@ export const updateRow: RequestHandler = async (req: Request, _res: Response, ne
209203
export const deleteRow: RequestHandler = async (req: Request, _res: Response, next: NextFunction,) => {
210204
const dbDataSource = await dbConnect(req);
211205
const { db_type } = req.session;
212-
const { primaryKey, value, deletedRow } = req.body
206+
const { value } = req.body
213207

214208
try{
215-
// let tableNameDelete = '';
216-
// switch (db_type) {
217-
// case 'oracle':
218-
// tableNameDelete = `"${(username as string).toUpperCase()}"."${tableName}"`;
219-
// break;
220-
// case 'mssql':
221-
// const schemaName: {[SchemaName: string]: string}[] = await dbDataSource.query(`SELECT SCHEMA_NAME() AS SchemaName;`);
222-
// tableNameDelete = `${schemaName[0].SchemaName}.${tableName}`;
223-
// break;
224-
// default:
225-
// tableNameDelete = tableName;
226-
// break;
227-
// };
228-
229209
const tableNameDelete = await Promise.resolve(tableNameFormat(req, dbDataSource));
230210

231-
if (primaryKey){
232-
// Deleting a row that has a PK
233-
await dbDataSource.query(`
234-
DELETE FROM ${tableNameDelete}
235-
WHERE ${db_type === 'oracle' ? `"${primaryKey}"` : primaryKey} = ${db_type === 'oracle' || db_type === 'mysql' ? `'${value}'` : value}
236-
`)
237-
238-
} else {
239-
// Deleting a row that does NOT have a PK
240-
const deleteEntries = Object.entries(deletedRow).filter(([_key, value]) => value !== null);
241-
const deleteKeys = deleteEntries.map(([key, _value]) => key);
242-
const deleteValues = deleteEntries.map(([_key, value]) => value);
243-
244-
let oracleKeyValueString = '';
245-
for (let i = 0; i < deleteKeys.length; i++) {
246-
oracleKeyValueString += `"${deleteKeys[i]}" = '${deleteValues[i]}'${i < deleteKeys.length - 1 ? ' AND ' : ''}`
247-
};
248-
const keyValueString = oracleKeyValueString.replace(/"/g, '');
211+
const deleteEntries = Object.entries(value).filter(([_key, value]) => value !== null);
212+
const deleteKeys = deleteEntries.map(([key, _value]) => key);
213+
const deleteValues = deleteEntries.map(([_key, value]) => value);
249214

250-
await dbDataSource.query(`
251-
DELETE FROM ${tableNameDelete}
252-
WHERE ${db_type === 'oracle' ? oracleKeyValueString : keyValueString }
253-
`)
215+
let oracleKeyValueString = '';
216+
for (let i = 0; i < deleteKeys.length; i++) {
217+
oracleKeyValueString += `"${deleteKeys[i]}" = '${deleteValues[i]}'${i < deleteKeys.length - 1 ? ' AND ' : ''}`
254218
};
219+
const keyValueString = oracleKeyValueString.replace(/"/g, '');
220+
221+
await dbDataSource.query(`
222+
DELETE FROM ${tableNameDelete}
223+
WHERE ${db_type === 'oracle' ? oracleKeyValueString : keyValueString }
224+
`)
255225

256226
dbDataSource.destroy();
257227
console.log('Database has been disconnected');
@@ -279,26 +249,33 @@ export const addNewDbColumn: RequestHandler = async (req: Request, _res: Respons
279249
console.log('tableNameAddColumn: ', tableNameAddColumn)
280250

281251
let keyValueString: string = '';
282-
let repeatingKeyValueString: string = '';
283252
let newColumnString: string = ''
284253

285254
columnData.forEach((el: NewColumn) => {
286-
if (db_type === 'mssql' || db_type === 'oracle') {
287-
repeatingKeyValueString += `ALTER TABLE ${tableNameAddColumn} ADD "${el.name}" ${el.type === 'AUTO_INCREMENT' ? 'INT' : el.type}${el.isPrimary ? ' PRIMARY KEY' : ''}${el.isNullable ? '' : ' NOT NULL'}${el.defaultValue ? ` DEFAULT ${el.defaultValue}` : ''}${el.type === 'AUTO_INCREMENT' ? ' AUTO_INCREMENT' : ''}; `
288-
} else {
255+
if (db_type === 'mssql') {
256+
keyValueString += `ALTER TABLE ${tableNameAddColumn} ADD "${el.name}" ${el.type === 'AUTO_INCREMENT' ? 'INT' : el.type}${el.isPrimary ? ' PRIMARY KEY' : ''}${el.isNullable ? '' : ' NOT NULL'}${el.defaultValue ? ` DEFAULT ${el.defaultValue}` : ''}${el.type === 'AUTO_INCREMENT' ? ' AUTO_INCREMENT' : ''}; `
257+
} else if(db_type === 'oracle') {
258+
let number: string = '';
259+
if (el.type.includes('VARCHAR')) {
260+
const regex = /\((\d+)\)/;
261+
const match = el.type.match(regex)
262+
number = (match as RegExpMatchArray)[1]
263+
}
264+
keyValueString += `ALTER TABLE ${tableNameAddColumn} ADD(${el.name} ${el.type.includes('VARCHAR') ? `VARCHAR2(${+number})` : el.type}${el.isPrimary ? ' PRIMARY KEY' : ''}${el.isNullable ? '' : ' NOT NULL'}${el.defaultValue ? ` DEFAULT ${el.defaultValue}` : ''}${el.type === 'AUTO_INCREMENT' ? ' AUTO_INCREMENT' : ''}))`
265+
} else {
289266
keyValueString += `ADD${db_type === 'postgres' ? ' COLUMN' : '' } ${ db_type === 'mysql' ? `${el.name}` : `"${el.name}"`} ${el.type === 'AUTO_INCREMENT' ? 'INT' : el.type}${el.isPrimary ? ' PRIMARY KEY' : ''}${el.isNullable ? '' : ' NOT NULL'}${el.defaultValue ? ` DEFAULT ${el.defaultValue}` : ''}${el.type === 'AUTO_INCREMENT' ? ' AUTO_INCREMENT' : ''}, `
290267
};
291268
});
292269

293270
if (db_type === 'mssql' || db_type === 'oracle') {
294-
newColumnString = repeatingKeyValueString.slice(0, -1);
271+
newColumnString = keyValueString.slice(0, -1);
295272
} else {
296273
newColumnString = keyValueString.slice(0, -2);
297-
}
274+
};
298275

299-
if (db_type === 'mssql') {
276+
if (db_type === 'mssql' || db_type === 'oracle') {
300277
const addedNewColumn: Promise<unknown> = await dbDataSource.query(`
301-
${repeatingKeyValueString}
278+
${newColumnString}
302279
`);
303280

304281
await dbDataSource.destroy();
@@ -328,27 +305,24 @@ export const addNewDbColumn: RequestHandler = async (req: Request, _res: Respons
328305

329306
export const updateDbColumn: RequestHandler = async (req: Request, _res: Response, next: NextFunction,) => {
330307
const dbDataSource = await dbConnect(req);
331-
const { db_type, username } = req.session;
308+
const { db_type } = req.session;
309+
const { columnName, schemaData, columnData } = req.body;
332310

333311
try{
334-
const updateColumnData: {[key: string]: string } = req.body;
335-
336-
const schemaName = db_type === 'mssql' ? await dbDataSource.query(`SELECT SCHEMA_NAME() AS SchemaName;`) : '';
337-
338-
const slicedTableName = updateColumnData.tableName.slice(7, updateColumnData.tableName.length + 1);
339-
const tableName: string = db_type === 'oracle' ? `"${(username as string).toUpperCase()}"."${slicedTableName}"` :
340-
db_type === 'mssql' ? `${schemaName[0].SchemaName}.${slicedTableName}` : updateColumnData.tableName;
312+
const tableNameUpdateColumn = await Promise.resolve(tableNameFormat(req, dbDataSource));
313+
console.log('schemaData: ', schemaData)
314+
console.log('columnData: ', columnData)
341315

342316

343-
const updatedColumn: Promise<unknown> = await dbDataSource.query(`
344-
ALTER TABLE ${tableName}
345-
${db_type === 'postgres' || db_type === 'microsoft' ? 'ALTER COLUMN' : 'MODIFY' } "${updateColumnData.columnName}" ${updateColumnData.dataType} ${db_type === 'postgres' ? updateColumnData.constraintName : null} ${updateColumnData.constraintExpression}
317+
await dbDataSource.query(`
318+
UPDATE ${tableNameUpdateColumn}
319+
${db_type === 'postgres' || db_type === 'microsoft' ? 'ALTER COLUMN' : 'MODIFY' } "${columnName}" ${db_type} ${ columnData.additional_constraint ? columnData.additional_constraint : ''};
346320
`);
347321

348322
dbDataSource.destroy();
349323
console.log('Database has been disconnected');
350-
console.log('addedForeignKey in helper: ', updatedColumn);
351-
return updatedColumn;
324+
// console.log('addedForeignKey in helper: ', updatedColumn);
325+
// return updatedColumn;
352326

353327
} catch (err: unknown) {
354328
console.log('Error occurred in the addedForeignKey middleware: ', err);
@@ -364,13 +338,13 @@ export const deleteColumn: RequestHandler = async (req: Request, _res: Response,
364338
const dbDataSource = await dbConnect(req)
365339
const { db_type } = req.session
366340
const { columnName } = req.body
367-
341+
console.log('we are in the helper functions: ', req.body)
368342
try{
369343
const columnTableNameDelete = await Promise.resolve(tableNameFormat(req, dbDataSource));
370344

371345
const deletedColumn: Promise<unknown> = await dbDataSource.query(`
372346
ALTER TABLE ${columnTableNameDelete}
373-
DROP${db_type !== 'mysql' ? ' COLUMN' : null} ${columnName}
347+
DROP${db_type !== 'mysql' ? ' COLUMN' : ''} ${columnName}
374348
`)
375349

376350
dbDataSource.destroy();

0 commit comments

Comments
 (0)