From 4408a91f275b8a896c6af430d5f3e4e9d8a071ba Mon Sep 17 00:00:00 2001
From: "github-classroom[bot]"
<66690702+github-classroom[bot]@users.noreply.github.com>
Date: Sat, 4 May 2024 12:14:28 +0000
Subject: [PATCH 01/15] Update GitHub Classroom Autograding Workflow
---
.github/workflows/classroom.yml | 222 ++++++++++++++++++++++++++++++--
1 file changed, 211 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/classroom.yml b/.github/workflows/classroom.yml
index dca83b024..f5a7f41d6 100644
--- a/.github/workflows/classroom.yml
+++ b/.github/workflows/classroom.yml
@@ -1,19 +1,219 @@
-name: GitHub Classroom Workflow
-
-on:
- - push
- - workflow_dispatch
-
+name: Autograding Tests
+'on':
+- workflow_dispatch
+- repository_dispatch
permissions:
checks: write
actions: read
contents: read
-
jobs:
- build:
- name: Autograding
+ run-autograding-tests:
runs-on: ubuntu-latest
if: github.actor != 'github-classroom[bot]'
steps:
- - uses: actions/checkout@v4
- - uses: education/autograding@v1
+ - name: Checkout code
+ uses: actions/checkout@v4
+ - name: Step-1 Test
+ id: step-1-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-1 Test
+ setup-command: npm install
+ command: npm run test:1
+ timeout: 10
+ max-score: 10
+ - name: Step-2 Test
+ id: step-2-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-2 Test
+ setup-command: npm install
+ command: npm run test:2
+ timeout: 10
+ max-score: 10
+ - name: Step-3 Test
+ id: step-3-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-3 Test
+ setup-command: npm install
+ command: npm run test:3
+ timeout: 10
+ max-score: 10
+ - name: Step-4 Test
+ id: step-4-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-4 Test
+ setup-command: npm install
+ command: npm run test:4
+ timeout: 10
+ - name: Step-5 Test
+ id: step-5-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-5 Test
+ setup-command: npm install
+ command: npm run test:5
+ timeout: 10
+ max-score: 10
+ - name: Step-6 Test
+ id: step-6-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-6 Test
+ setup-command: npm install
+ command: npm run test:6
+ timeout: 10
+ max-score: 10
+ - name: Step-7 Test
+ id: step-7-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-7 Test
+ setup-command: npm install
+ command: npm run test:7
+ timeout: 10
+ max-score: 10
+ - name: Step-8 Test
+ id: step-8-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-8 Test
+ setup-command: npm install
+ command: npm run test:8
+ timeout: 10
+ max-score: 10
+ - name: Step-9 Test
+ id: step-9-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-9 Test
+ setup-command: npm install
+ command: npm run test:9
+ timeout: 10
+ max-score: 10
+ - name: Step-10 Test
+ id: step-10-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-10 Test
+ setup-command: npm install
+ command: npm run test:10
+ timeout: 10
+ max-score: 10
+ - name: Step-11 Test
+ id: step-11-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-11 Test
+ setup-command: npm install
+ command: npm run test:11
+ timeout: 10
+ max-score: 10
+ - name: Step-12 Test
+ id: step-12-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-12 Test
+ setup-command: npm install
+ command: npm run test:12
+ timeout: 10
+ max-score: 10
+ - name: Step-13 Test
+ id: step-13-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-13 Test
+ setup-command: npm install
+ command: npm run test:13
+ timeout: 10
+ max-score: 10
+ - name: Step-14 Test
+ id: step-14-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-14 Test
+ setup-command: npm install
+ command: npm run test:14
+ timeout: 10
+ max-score: 10
+ - name: Step-15 Test
+ id: step-15-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-15 Test
+ setup-command: npm install
+ command: npm run test:15
+ timeout: 10
+ max-score: 10
+ - name: Step-16 Test
+ id: step-16-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-16 Test
+ setup-command: npm install
+ command: npm run test:16
+ timeout: 10
+ max-score: 10
+ - name: Step-17 Test
+ id: step-17-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-17 Test
+ setup-command: npm install
+ command: npm run test:17
+ timeout: 10
+ max-score: 10
+ - name: Step-18 Test
+ id: step-18-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-18 Test
+ setup-command: npm install
+ command: npm run test:18
+ timeout: 10
+ max-score: 10
+ - name: Step-19 Test
+ id: step-19-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-19 Test
+ setup-command: npm install
+ command: npm run test:19
+ timeout: 10
+ max-score: 10
+ - name: Step-20 Test
+ id: step-20-test
+ uses: classroom-resources/autograding-command-grader@v1
+ with:
+ test-name: Step-20 Test
+ setup-command: npm install
+ command: npm run test:20
+ timeout: 10
+ max-score: 10
+ - name: Autograding Reporter
+ uses: classroom-resources/autograding-grading-reporter@v1
+ env:
+ STEP-1-TEST_RESULTS: "${{steps.step-1-test.outputs.result}}"
+ STEP-2-TEST_RESULTS: "${{steps.step-2-test.outputs.result}}"
+ STEP-3-TEST_RESULTS: "${{steps.step-3-test.outputs.result}}"
+ STEP-4-TEST_RESULTS: "${{steps.step-4-test.outputs.result}}"
+ STEP-5-TEST_RESULTS: "${{steps.step-5-test.outputs.result}}"
+ STEP-6-TEST_RESULTS: "${{steps.step-6-test.outputs.result}}"
+ STEP-7-TEST_RESULTS: "${{steps.step-7-test.outputs.result}}"
+ STEP-8-TEST_RESULTS: "${{steps.step-8-test.outputs.result}}"
+ STEP-9-TEST_RESULTS: "${{steps.step-9-test.outputs.result}}"
+ STEP-10-TEST_RESULTS: "${{steps.step-10-test.outputs.result}}"
+ STEP-11-TEST_RESULTS: "${{steps.step-11-test.outputs.result}}"
+ STEP-12-TEST_RESULTS: "${{steps.step-12-test.outputs.result}}"
+ STEP-13-TEST_RESULTS: "${{steps.step-13-test.outputs.result}}"
+ STEP-14-TEST_RESULTS: "${{steps.step-14-test.outputs.result}}"
+ STEP-15-TEST_RESULTS: "${{steps.step-15-test.outputs.result}}"
+ STEP-16-TEST_RESULTS: "${{steps.step-16-test.outputs.result}}"
+ STEP-17-TEST_RESULTS: "${{steps.step-17-test.outputs.result}}"
+ STEP-18-TEST_RESULTS: "${{steps.step-18-test.outputs.result}}"
+ STEP-19-TEST_RESULTS: "${{steps.step-19-test.outputs.result}}"
+ STEP-20-TEST_RESULTS: "${{steps.step-20-test.outputs.result}}"
+ with:
+ runners: step-1-test,step-2-test,step-3-test,step-4-test,step-5-test,step-6-test,step-7-test,step-8-test,step-9-test,step-10-test,step-11-test,step-12-test,step-13-test,step-14-test,step-15-test,step-16-test,step-17-test,step-18-test,step-19-test,step-20-test
From 075a0936fd9ca15f7d488e1459c590d38f77bb5e Mon Sep 17 00:00:00 2001
From: "github-classroom[bot]"
<66690702+github-classroom[bot]@users.noreply.github.com>
Date: Sat, 4 May 2024 12:14:29 +0000
Subject: [PATCH 02/15] GitHub Classroom Feedback
---
.github/.keep | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 .github/.keep
diff --git a/.github/.keep b/.github/.keep
new file mode 100644
index 000000000..e69de29bb
From 9572d0d78534e0f8c398fd813b48f7c38c741879 Mon Sep 17 00:00:00 2001
From: "github-classroom[bot]"
<66690702+github-classroom[bot]@users.noreply.github.com>
Date: Sat, 4 May 2024 12:14:29 +0000
Subject: [PATCH 03/15] Setting up GitHub Classroom Feedback
From 8019bf6868912d2acf9eb13519695a342427668c Mon Sep 17 00:00:00 2001
From: "github-classroom[bot]"
<66690702+github-classroom[bot]@users.noreply.github.com>
Date: Sat, 4 May 2024 12:14:31 +0000
Subject: [PATCH 04/15] add online IDE url
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index eadfc715a..e45b2a477 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+[](https://classroom.github.com/online_ide?assignment_repo_id=14973533&assignment_repo_type=AssignmentRepo)
StylusDB SQL
A SQL database engine written in JavaScript
From 3a18a03060ca5db42ffb151bf5eb433edcb379cb Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 22:03:02 +0530
Subject: [PATCH 05/15] 01.md tutorial done
---
src/index.js | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 src/index.js
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 000000000..e69de29bb
From 3f62ae542a072a5d5f8ddb2763181c9ff40b8613 Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 22:16:42 +0530
Subject: [PATCH 06/15] completed tutorial 2. Test cases passed: 2
---
sample.csv | 4 ++++
src/csvReader.js | 20 ++++++++++++++++++++
2 files changed, 24 insertions(+)
create mode 100644 sample.csv
diff --git a/sample.csv b/sample.csv
new file mode 100644
index 000000000..9e7a9fa25
--- /dev/null
+++ b/sample.csv
@@ -0,0 +1,4 @@
+id,name,age
+1,John,30
+2,Jane,25
+3,Bob,22
\ No newline at end of file
diff --git a/src/csvReader.js b/src/csvReader.js
index e69de29bb..c39210a98 100644
--- a/src/csvReader.js
+++ b/src/csvReader.js
@@ -0,0 +1,20 @@
+const fs = require('fs');
+const csv = require('csv-parser');
+
+function readCSV(filePath) {
+ const results = [];
+
+ return new Promise((resolve, reject) => {
+ fs.createReadStream(filePath)
+ .pipe(csv())
+ .on('data', (data) => results.push(data))
+ .on('end', () => {
+ resolve(results);
+ })
+ .on('error', (error) => {
+ reject(error);
+ });
+ });
+}
+
+module.exports = readCSV;
\ No newline at end of file
From 483cf2eb7d6d58d557ab72a9d1902ff023585042 Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 22:19:53 +0530
Subject: [PATCH 07/15] completed tutorial 3. Test cases passed: 3
---
src/queryParser.js | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 src/queryParser.js
diff --git a/src/queryParser.js b/src/queryParser.js
new file mode 100644
index 000000000..8cba13b8a
--- /dev/null
+++ b/src/queryParser.js
@@ -0,0 +1,16 @@
+function parseQuery(query) {
+ const selectRegex = /SELECT (.+) FROM (.+)/i;
+ const match = query.match(selectRegex);
+
+ if (match) {
+ const [, fields, table] = match;
+ return {
+ fields: fields.split(',').map(field => field.trim()),
+ table: table.trim()
+ };
+ } else {
+ throw new Error('Invalid query format');
+ }
+}
+
+module.exports = parseQuery;
\ No newline at end of file
From 8c37ca00c550a4adbf1f4a2de264a23bc625627f Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 22:25:48 +0530
Subject: [PATCH 08/15] completed tutorial 4. Test cases passed: 4
---
src/index.js | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/index.js b/src/index.js
index e69de29bb..4abc0e143 100644
--- a/src/index.js
+++ b/src/index.js
@@ -0,0 +1,18 @@
+const parseQuery = require('./queryParser');
+const readCSV = require('./csvReader');
+
+async function executeSELECTQuery(query) {
+ const { fields, table } = parseQuery(query);
+ const data = await readCSV(`${table}.csv`);
+
+ // Filter the fields based on the query
+ return data.map(row => {
+ const filteredRow = {};
+ fields.forEach(field => {
+ filteredRow[field] = row[field];
+ });
+ return filteredRow;
+ });
+}
+
+module.exports = executeSELECTQuery;
\ No newline at end of file
From e0680427074227d004320736bda30a8ec99636a3 Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 22:27:52 +0530
Subject: [PATCH 09/15] completed tutorial 5. Test cases passed: 5
---
src/queryParser.js | 36 +++++++++++++++++++++++-------------
1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/src/queryParser.js b/src/queryParser.js
index 8cba13b8a..c0775a3d0 100644
--- a/src/queryParser.js
+++ b/src/queryParser.js
@@ -1,16 +1,26 @@
-function parseQuery(query) {
- const selectRegex = /SELECT (.+) FROM (.+)/i;
- const match = query.match(selectRegex);
+const parseQuery = require('./queryParser');
+const readCSV = require('./csvReader');
- if (match) {
- const [, fields, table] = match;
- return {
- fields: fields.split(',').map(field => field.trim()),
- table: table.trim()
- };
- } else {
- throw new Error('Invalid query format');
- }
+async function executeSELECTQuery(query) {
+ const { fields, table, whereClause } = parseQuery(query);
+ const data = await readCSV(`${table}.csv`);
+
+ // Filtering based on WHERE clause
+ const filteredData = whereClause
+ ? data.filter(row => {
+ const [field, value] = whereClause.split('=').map(s => s.trim());
+ return row[field] === value;
+ })
+ : data;
+
+ // Selecting the specified fields
+ return filteredData.map(row => {
+ const selectedRow = {};
+ fields.forEach(field => {
+ selectedRow[field] = row[field];
+ });
+ return selectedRow;
+ });
}
-module.exports = parseQuery;
\ No newline at end of file
+module.exports = executeSELECTQuery;
\ No newline at end of file
From d9c17ce33f0f855fb7c4c6cece0fc2a506cce71e Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 22:29:38 +0530
Subject: [PATCH 10/15] completed tutorial 6. Test cases passed: 7
---
src/index.js | 22 +++++++++++++++-------
src/queryParser.js | 42 +++++++++++++++++++++---------------------
2 files changed, 36 insertions(+), 28 deletions(-)
diff --git a/src/index.js b/src/index.js
index 4abc0e143..93b8affea 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,16 +2,24 @@ const parseQuery = require('./queryParser');
const readCSV = require('./csvReader');
async function executeSELECTQuery(query) {
- const { fields, table } = parseQuery(query);
+ const { fields, table, whereClauses } = parseQuery(query);
const data = await readCSV(`${table}.csv`);
-
- // Filter the fields based on the query
- return data.map(row => {
- const filteredRow = {};
+
+ // Apply WHERE clause filtering
+ const filteredData = whereClauses.length > 0
+ ? data.filter(row => whereClauses.every(clause => {
+ // You can expand this to handle different operators
+ return row[clause.field] === clause.value;
+ }))
+ : data;
+
+ // Select the specified fields
+ return filteredData.map(row => {
+ const selectedRow = {};
fields.forEach(field => {
- filteredRow[field] = row[field];
+ selectedRow[field] = row[field];
});
- return filteredRow;
+ return selectedRow;
});
}
diff --git a/src/queryParser.js b/src/queryParser.js
index c0775a3d0..82745d43b 100644
--- a/src/queryParser.js
+++ b/src/queryParser.js
@@ -1,26 +1,26 @@
-const parseQuery = require('./queryParser');
-const readCSV = require('./csvReader');
+function parseQuery(query) {
+ const selectRegex = /SELECT (.+?) FROM (.+?)(?: WHERE (.*))?$/i;
+ const match = query.match(selectRegex);
-async function executeSELECTQuery(query) {
- const { fields, table, whereClause } = parseQuery(query);
- const data = await readCSV(`${table}.csv`);
-
- // Filtering based on WHERE clause
- const filteredData = whereClause
- ? data.filter(row => {
- const [field, value] = whereClause.split('=').map(s => s.trim());
- return row[field] === value;
- })
- : data;
+ if (match) {
+ const [, fields, table, whereString] = match;
+ const whereClauses = whereString ? parseWhereClause(whereString) : [];
+ return {
+ fields: fields.split(',').map(field => field.trim()),
+ table: table.trim(),
+ whereClauses
+ };
+ } else {
+ throw new Error('Invalid query format');
+ }
+}
- // Selecting the specified fields
- return filteredData.map(row => {
- const selectedRow = {};
- fields.forEach(field => {
- selectedRow[field] = row[field];
- });
- return selectedRow;
+function parseWhereClause(whereString) {
+ const conditions = whereString.split(/ AND | OR /i);
+ return conditions.map(condition => {
+ const [field, operator, value] = condition.split(/\s+/);
+ return { field, operator, value };
});
}
-module.exports = executeSELECTQuery;
\ No newline at end of file
+module.exports = parseQuery;
\ No newline at end of file
From bb1ff02ab8daa399bbf7fcda3895e3e3a0df1680 Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 22:33:03 +0530
Subject: [PATCH 11/15] completed tutorial 7. Test cases passed: 9
---
src/index.js | 18 ++++++++++++++----
src/queryParser.js | 12 ++++++++----
2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/src/index.js b/src/index.js
index 93b8affea..aba653378 100644
--- a/src/index.js
+++ b/src/index.js
@@ -7,10 +7,7 @@ async function executeSELECTQuery(query) {
// Apply WHERE clause filtering
const filteredData = whereClauses.length > 0
- ? data.filter(row => whereClauses.every(clause => {
- // You can expand this to handle different operators
- return row[clause.field] === clause.value;
- }))
+ ? data.filter(row => whereClauses.every(clause => evaluateCondition(row, clause)))
: data;
// Select the specified fields
@@ -23,4 +20,17 @@ async function executeSELECTQuery(query) {
});
}
+function evaluateCondition(row, clause) {
+ const { field, operator, value } = clause;
+ switch (operator) {
+ case '=': return row[field] === value;
+ case '!=': return row[field] !== value;
+ case '>': return row[field] > value;
+ case '<': return row[field] < value;
+ case '>=': return row[field] >= value;
+ case '<=': return row[field] <= value;
+ default: throw new Error(`Unsupported operator: ${operator}`);
+ }
+}
+
module.exports = executeSELECTQuery;
\ No newline at end of file
diff --git a/src/queryParser.js b/src/queryParser.js
index 82745d43b..55eea7d14 100644
--- a/src/queryParser.js
+++ b/src/queryParser.js
@@ -16,10 +16,14 @@ function parseQuery(query) {
}
function parseWhereClause(whereString) {
- const conditions = whereString.split(/ AND | OR /i);
- return conditions.map(condition => {
- const [field, operator, value] = condition.split(/\s+/);
- return { field, operator, value };
+ const conditionRegex = /(.*?)(=|!=|>|<|>=|<=)(.*)/;
+ return whereString.split(/ AND | OR /i).map(conditionString => {
+ const match = conditionString.match(conditionRegex);
+ if (match) {
+ const [, field, operator, value] = match;
+ return { field: field.trim(), operator, value: value.trim() };
+ }
+ throw new Error('Invalid WHERE clause format');
});
}
From f874449de5283340afd08f1849b190c665f1cb9c Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 22:38:33 +0530
Subject: [PATCH 12/15] completed tutorial 8. Test cases passed: 13
---
enrollment.csv | 5 +++
src/index.js | 27 ++++++++++++++--
src/queryParser.js | 68 ++++++++++++++++++++++++++++++++-------
sample.csv => student.csv | 0
4 files changed, 85 insertions(+), 15 deletions(-)
create mode 100644 enrollment.csv
rename sample.csv => student.csv (100%)
diff --git a/enrollment.csv b/enrollment.csv
new file mode 100644
index 000000000..a81a90294
--- /dev/null
+++ b/enrollment.csv
@@ -0,0 +1,5 @@
+student_id,course
+1,Mathematics
+1,Physics
+2,Chemistry
+3,Mathematics
diff --git a/src/index.js b/src/index.js
index aba653378..ff175826c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,10 +2,30 @@ const parseQuery = require('./queryParser');
const readCSV = require('./csvReader');
async function executeSELECTQuery(query) {
- const { fields, table, whereClauses } = parseQuery(query);
- const data = await readCSV(`${table}.csv`);
+ const { fields, table, whereClauses, joinTable, joinCondition } = parseQuery(query);
+ let data = await readCSV(`${table}.csv`);
- // Apply WHERE clause filtering
+ // Perform INNER JOIN if specified
+ if (joinTable && joinCondition) {
+ const joinData = await readCSV(`${joinTable}.csv`);
+ data = data.flatMap(mainRow => {
+ return joinData
+ .filter(joinRow => {
+ const mainValue = mainRow[joinCondition.left.split('.')[1]];
+ const joinValue = joinRow[joinCondition.right.split('.')[1]];
+ return mainValue === joinValue;
+ })
+ .map(joinRow => {
+ return fields.reduce((acc, field) => {
+ const [tableName, fieldName] = field.split('.');
+ acc[field] = tableName === table ? mainRow[fieldName] : joinRow[fieldName];
+ return acc;
+ }, {});
+ });
+ });
+ }
+
+ // Apply WHERE clause filtering after JOIN (or on the original data if no join)
const filteredData = whereClauses.length > 0
? data.filter(row => whereClauses.every(clause => evaluateCondition(row, clause)))
: data;
@@ -14,6 +34,7 @@ async function executeSELECTQuery(query) {
return filteredData.map(row => {
const selectedRow = {};
fields.forEach(field => {
+ // Assuming 'field' is just the column name without table prefix
selectedRow[field] = row[field];
});
return selectedRow;
diff --git a/src/queryParser.js b/src/queryParser.js
index 55eea7d14..26846dfce 100644
--- a/src/queryParser.js
+++ b/src/queryParser.js
@@ -1,18 +1,62 @@
function parseQuery(query) {
- const selectRegex = /SELECT (.+?) FROM (.+?)(?: WHERE (.*))?$/i;
- const match = query.match(selectRegex);
-
- if (match) {
- const [, fields, table, whereString] = match;
- const whereClauses = whereString ? parseWhereClause(whereString) : [];
- return {
- fields: fields.split(',').map(field => field.trim()),
- table: table.trim(),
- whereClauses
+ // First, let's trim the query to remove any leading/trailing whitespaces
+ query = query.trim();
+
+ // Initialize variables for different parts of the query
+ let selectPart, fromPart;
+
+ // Split the query at the WHERE clause if it exists
+ const whereSplit = query.split(/\sWHERE\s/i);
+ query = whereSplit[0]; // Everything before WHERE clause
+
+ // WHERE clause is the second part after splitting, if it exists
+ const whereClause = whereSplit.length > 1 ? whereSplit[1].trim() : null;
+
+ // Split the remaining query at the JOIN clause if it exists
+ const joinSplit = query.split(/\sINNER JOIN\s/i);
+ selectPart = joinSplit[0].trim(); // Everything before JOIN clause
+
+ // JOIN clause is the second part after splitting, if it exists
+ const joinPart = joinSplit.length > 1 ? joinSplit[1].trim() : null;
+
+ // Parse the SELECT part
+ const selectRegex = /^SELECT\s(.+?)\sFROM\s(.+)/i;
+ const selectMatch = selectPart.match(selectRegex);
+ if (!selectMatch) {
+ throw new Error('Invalid SELECT format');
+ }
+
+ const [, fields, table] = selectMatch;
+
+ // Parse the JOIN part if it exists
+ let joinTable = null, joinCondition = null;
+ if (joinPart) {
+ const joinRegex = /^(.+?)\sON\s([\w.]+)\s*=\s*([\w.]+)/i;
+ const joinMatch = joinPart.match(joinRegex);
+ if (!joinMatch) {
+ throw new Error('Invalid JOIN format');
+ }
+
+ joinTable = joinMatch[1].trim();
+ joinCondition = {
+ left: joinMatch[2].trim(),
+ right: joinMatch[3].trim()
};
- } else {
- throw new Error('Invalid query format');
}
+
+ // Parse the WHERE part if it exists
+ let whereClauses = [];
+ if (whereClause) {
+ whereClauses = parseWhereClause(whereClause);
+ }
+
+ return {
+ fields: fields.split(',').map(field => field.trim()),
+ table: table.trim(),
+ whereClauses,
+ joinTable,
+ joinCondition
+ };
}
function parseWhereClause(whereString) {
diff --git a/sample.csv b/student.csv
similarity index 100%
rename from sample.csv
rename to student.csv
From e41fe65c14ba24716a3197760d25e40d286a3a1a Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 22:54:33 +0530
Subject: [PATCH 13/15] added cli.js and queryExecutor.js
---
enrollment.csv | 1 +
src/cli.js | 51 +++++
src/csvReader.js | 39 ++--
src/index.js | 77 ++------
src/queryExecutor.js | 451 +++++++++++++++++++++++++++++++++++++++++++
src/queryParser.js | 252 +++++++++++++++++-------
student.csv | 3 +-
7 files changed, 734 insertions(+), 140 deletions(-)
create mode 100644 src/cli.js
create mode 100644 src/queryExecutor.js
diff --git a/enrollment.csv b/enrollment.csv
index a81a90294..e80af8d93 100644
--- a/enrollment.csv
+++ b/enrollment.csv
@@ -3,3 +3,4 @@ student_id,course
1,Physics
2,Chemistry
3,Mathematics
+5,Biology
\ No newline at end of file
diff --git a/src/cli.js b/src/cli.js
new file mode 100644
index 000000000..458a6fe42
--- /dev/null
+++ b/src/cli.js
@@ -0,0 +1,51 @@
+#!/usr/bin/env node
+
+const readline = require ('readline');
+const {
+ executeSELECTQuery,
+ executeINSERTQuery,
+ executeDELETEQuery,
+} = require ('./index');
+
+const rl = readline.createInterface ({
+ input: process.stdin,
+ output: process.stdout,
+});
+
+rl.setPrompt ('SQL> ');
+console.log (
+ 'SQL Query Engine CLI. Enter your SQL commands, or type "exit" to quit.'
+);
+
+rl.prompt ();
+
+rl
+ .on ('line', async line => {
+ if (line.toLowerCase () === 'exit') {
+ rl.close ();
+ return;
+ }
+
+ try {
+ if (line.toLowerCase ().startsWith ('select')) {
+ const result = await executeSELECTQuery (line);
+ console.log ('Result:', result);
+ } else if (line.toLowerCase ().startsWith ('insert into')) {
+ const result = await executeINSERTQuery (line);
+ console.log (result.message);
+ } else if (line.toLowerCase ().startsWith ('delete from')) {
+ const result = await executeDELETEQuery (line);
+ console.log (result.message);
+ } else {
+ console.log ('Unsupported command');
+ }
+ } catch (error) {
+ console.error ('Error:', error.message);
+ }
+
+ rl.prompt ();
+ })
+ .on ('close', () => {
+ console.log ('Exiting SQL CLI');
+ process.exit (0);
+ });
\ No newline at end of file
diff --git a/src/csvReader.js b/src/csvReader.js
index c39210a98..20ecfd130 100644
--- a/src/csvReader.js
+++ b/src/csvReader.js
@@ -1,20 +1,27 @@
-const fs = require('fs');
-const csv = require('csv-parser');
+const fs = require ('fs');
+const csv = require ('csv-parser');
+const {parse} = require ('json2csv');
-function readCSV(filePath) {
- const results = [];
+function readCSV (filePath) {
+ const results = [];
- return new Promise((resolve, reject) => {
- fs.createReadStream(filePath)
- .pipe(csv())
- .on('data', (data) => results.push(data))
- .on('end', () => {
- resolve(results);
- })
- .on('error', (error) => {
- reject(error);
- });
- });
+ return new Promise ((resolve, reject) => {
+ fs
+ .createReadStream (filePath)
+ .pipe (csv ())
+ .on ('data', data => results.push (data))
+ .on ('end', () => {
+ resolve (results);
+ })
+ .on ('error', error => {
+ reject (error);
+ });
+ });
}
-module.exports = readCSV;
\ No newline at end of file
+async function writeCSV (filename, data) {
+ const csv = parse (data);
+ fs.writeFileSync (filename, csv);
+}
+
+module.exports = {readCSV, writeCSV};
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index ff175826c..9cbe0d228 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,57 +1,22 @@
-const parseQuery = require('./queryParser');
-const readCSV = require('./csvReader');
+const {readCSV, writeCSV} = require ('./csvReader');
+const {
+ parseSelectQuery,
+ parseInsertQuery,
+ parseDeleteQuery,
+} = require ('./queryParser');
+const {
+ executeSELECTQuery,
+ executeINSERTQuery,
+ executeDELETEQuery,
+} = require ('./queryExecuter');
-async function executeSELECTQuery(query) {
- const { fields, table, whereClauses, joinTable, joinCondition } = parseQuery(query);
- let data = await readCSV(`${table}.csv`);
-
- // Perform INNER JOIN if specified
- if (joinTable && joinCondition) {
- const joinData = await readCSV(`${joinTable}.csv`);
- data = data.flatMap(mainRow => {
- return joinData
- .filter(joinRow => {
- const mainValue = mainRow[joinCondition.left.split('.')[1]];
- const joinValue = joinRow[joinCondition.right.split('.')[1]];
- return mainValue === joinValue;
- })
- .map(joinRow => {
- return fields.reduce((acc, field) => {
- const [tableName, fieldName] = field.split('.');
- acc[field] = tableName === table ? mainRow[fieldName] : joinRow[fieldName];
- return acc;
- }, {});
- });
- });
- }
-
- // Apply WHERE clause filtering after JOIN (or on the original data if no join)
- const filteredData = whereClauses.length > 0
- ? data.filter(row => whereClauses.every(clause => evaluateCondition(row, clause)))
- : data;
-
- // Select the specified fields
- return filteredData.map(row => {
- const selectedRow = {};
- fields.forEach(field => {
- // Assuming 'field' is just the column name without table prefix
- selectedRow[field] = row[field];
- });
- return selectedRow;
- });
-}
-
-function evaluateCondition(row, clause) {
- const { field, operator, value } = clause;
- switch (operator) {
- case '=': return row[field] === value;
- case '!=': return row[field] !== value;
- case '>': return row[field] > value;
- case '<': return row[field] < value;
- case '>=': return row[field] >= value;
- case '<=': return row[field] <= value;
- default: throw new Error(`Unsupported operator: ${operator}`);
- }
-}
-
-module.exports = executeSELECTQuery;
\ No newline at end of file
+module.exports = {
+ readCSV,
+ writeCSV,
+ executeSELECTQuery,
+ executeINSERTQuery,
+ executeDELETEQuery,
+ parseSelectQuery,
+ parseInsertQuery,
+ parseDeleteQuery,
+};
\ No newline at end of file
diff --git a/src/queryExecutor.js b/src/queryExecutor.js
new file mode 100644
index 000000000..02d89e3ec
--- /dev/null
+++ b/src/queryExecutor.js
@@ -0,0 +1,451 @@
+const {
+ parseSelectQuery,
+ parseInsertQuery,
+ parseDeleteQuery,
+} = require('./queryParser');
+const { readCSV, writeCSV } = require('./csvReader');
+
+function performInnerJoin(data, joinData, joinCondition, fields, table) {
+ return data.flatMap(mainRow => {
+ return joinData
+ .filter(joinRow => {
+ const mainValue = mainRow[joinCondition.left.split('.')[1]];
+ const joinValue = joinRow[joinCondition.right.split('.')[1]];
+ return mainValue === joinValue;
+ })
+ .map(joinRow => {
+ return fields.reduce((acc, field) => {
+ const [tableName, fieldName] = field.split('.');
+ acc[field] = tableName === table
+ ? mainRow[fieldName]
+ : joinRow[fieldName];
+ return acc;
+ }, {});
+ });
+ });
+}
+
+function performLeftJoin(data, joinData, joinCondition, fields, table) {
+ return data.flatMap(mainRow => {
+ const matchingJoinRows = joinData.filter(joinRow => {
+ const mainValue = getValueFromRow(mainRow, joinCondition.left);
+ const joinValue = getValueFromRow(joinRow, joinCondition.right);
+ return mainValue === joinValue;
+ });
+
+ if (matchingJoinRows.length === 0) {
+ return [createResultRow(mainRow, null, fields, table, true)];
+ }
+
+ return matchingJoinRows.map(joinRow =>
+ createResultRow(mainRow, joinRow, fields, table, true)
+ );
+ });
+}
+
+function getValueFromRow(row, compoundFieldName) {
+ const [tableName, fieldName] = compoundFieldName.split('.');
+ return row[`${tableName}.${fieldName}`] || row[fieldName];
+}
+
+function performRightJoin(data, joinData, joinCondition, fields, table) {
+ // Cache the structure of a main table row (keys only)
+ const mainTableRowStructure = data.length > 0
+ ? Object.keys(data[0]).reduce((acc, key) => {
+ acc[key] = null; // Set all values to null initially
+ return acc;
+ }, {})
+ : {};
+
+ return joinData.map(joinRow => {
+ const mainRowMatch = data.find(mainRow => {
+ const mainValue = getValueFromRow(mainRow, joinCondition.left);
+ const joinValue = getValueFromRow(joinRow, joinCondition.right);
+ return mainValue === joinValue;
+ });
+
+ // Use the cached structure if no match is found
+ const mainRowToUse = mainRowMatch || mainTableRowStructure;
+
+ // Include all necessary fields from the 'student' table
+ return createResultRow(mainRowToUse, joinRow, fields, table, true);
+ });
+}
+
+function createResultRow(
+ mainRow,
+ joinRow,
+ fields,
+ table,
+ includeAllMainFields
+) {
+ const resultRow = {};
+
+ if (includeAllMainFields) {
+ // Include all fields from the main table
+ Object.keys(mainRow || {}).forEach(key => {
+ const prefixedKey = `${table}.${key}`;
+ resultRow[prefixedKey] = mainRow ? mainRow[key] : null;
+ });
+ }
+
+ // Now, add or overwrite with the fields specified in the query
+ fields.forEach(field => {
+ const [tableName, fieldName] = field.includes('.')
+ ? field.split('.')
+ : [table, field];
+ resultRow[field] = tableName === table && mainRow
+ ? mainRow[fieldName]
+ : joinRow ? joinRow[fieldName] : null;
+ });
+
+ return resultRow;
+}
+
+function evaluateCondition(row, clause) {
+ let { field, operator, value } = clause;
+
+ // Check if the field exists in the row
+ if (row[field] === undefined) {
+ throw new Error(`Invalid field: ${field}`);
+ }
+
+ // Parse row value and condition value based on their actual types
+ const rowValue = parseValue(row[field]);
+ let conditionValue = parseValue(value);
+
+ if (operator === 'LIKE') {
+ // Transform SQL LIKE pattern to JavaScript RegExp pattern
+ const regexPattern =
+ '^' + value.replace(/%/g, '.*').replace(/_/g, '.') + '$';
+ const regex = new RegExp(regexPattern, 'i'); // 'i' for case-insensitive matching
+ return regex.test(row[field]);
+ }
+
+ switch (operator) {
+ case '=':
+ return rowValue === conditionValue;
+ case '!=':
+ return rowValue !== conditionValue;
+ case '>':
+ return rowValue > conditionValue;
+ case '<':
+ return rowValue < conditionValue;
+ case '>=':
+ return rowValue >= conditionValue;
+ case '<=':
+ return rowValue <= conditionValue;
+ default:
+ throw new Error(`Unsupported operator: ${operator}`);
+ }
+}
+
+// Helper function to parse value based on its apparent type
+function parseValue(value) {
+ // Return null or undefined as is
+ if (value === null || value === undefined) {
+ return value;
+ }
+
+ // If the value is a string enclosed in single or double quotes, remove them
+ if (
+ typeof value === 'string' &&
+ ((value.startsWith("'") && value.endsWith("'")) ||
+ (value.startsWith('"') && value.endsWith('"')))
+ ) {
+ value = value.substring(1, value.length - 1);
+ }
+
+ // Check if value is a number
+ if (!isNaN(value) && value.trim() !== '') {
+ return Number(value);
+ }
+ // Assume value is a string if not a number
+ return value;
+}
+
+function applyGroupBy(data, groupByFields, aggregateFunctions) {
+ const groupResults = {};
+
+ data.forEach(row => {
+ // Generate a key for the group
+ const groupKey = groupByFields.map(field => row[field]).join('-');
+
+ // Initialize group in results if it doesn't exist
+ if (!groupResults[groupKey]) {
+ groupResults[groupKey] = { count: 0, sums: {}, mins: {}, maxes: {} };
+ groupByFields.forEach(
+ field => (groupResults[groupKey][field] = row[field])
+ );
+ }
+
+ // Aggregate calculations
+ groupResults[groupKey].count += 1;
+ aggregateFunctions.forEach(func => {
+ const match = /(\w+)\((\w+)\)/.exec(func);
+ if (match) {
+ const [, aggFunc, aggField] = match;
+ const value = parseFloat(row[aggField]);
+
+ switch (aggFunc.toUpperCase()) {
+ case 'SUM':
+ groupResults[groupKey].sums[aggField] =
+ (groupResults[groupKey].sums[aggField] || 0) + value;
+ break;
+ case 'MIN':
+ groupResults[groupKey].mins[aggField] = Math.min(
+ groupResults[groupKey].mins[aggField] || value,
+ value
+ );
+ break;
+ case 'MAX':
+ groupResults[groupKey].maxes[aggField] = Math.max(
+ groupResults[groupKey].maxes[aggField] || value,
+ value
+ );
+ break;
+ // Additional aggregate functions can be added here
+ }
+ }
+ });
+ });
+
+ // Convert grouped results into an array format
+ return Object.values(groupResults).map(group => {
+ // Construct the final grouped object based on required fields
+ const finalGroup = {};
+ groupByFields.forEach(field => (finalGroup[field] = group[field]));
+ aggregateFunctions.forEach(func => {
+ const match = /(\w+)\((\*|\w+)\)/.exec(func);
+ if (match) {
+ const [, aggFunc, aggField] = match;
+ switch (aggFunc.toUpperCase()) {
+ case 'SUM':
+ finalGroup[func] = group.sums[aggField];
+ break;
+ case 'MIN':
+ finalGroup[func] = group.mins[aggField];
+ break;
+ case 'MAX':
+ finalGroup[func] = group.maxes[aggField];
+ break;
+ case 'COUNT':
+ finalGroup[func] = group.count;
+ break;
+ // Additional aggregate functions can be handled here
+ }
+ }
+ });
+
+ return finalGroup;
+ });
+}
+
+async function executeSELECTQuery(query) {
+ try {
+ const {
+ fields,
+ table,
+ whereClauses,
+ joinType,
+ joinTable,
+ joinCondition,
+ groupByFields,
+ hasAggregateWithoutGroupBy,
+ orderByFields,
+ limit,
+ isDistinct,
+ } = parseSelectQuery(query);
+ let data = await readCSV(`${table}.csv`);
+
+ // Perform INNER JOIN if specified
+ if (joinTable && joinCondition) {
+ const joinData = await readCSV(`${joinTable}.csv`);
+ switch (joinType.toUpperCase()) {
+ case 'INNER':
+ data = performInnerJoin(
+ data,
+ joinData,
+ joinCondition,
+ fields,
+ table
+ );
+ break;
+ case 'LEFT':
+ data = performLeftJoin(data, joinData, joinCondition, fields, table);
+ break;
+ case 'RIGHT':
+ data = performRightJoin(
+ data,
+ joinData,
+ joinCondition,
+ fields,
+ table
+ );
+ break;
+ default:
+ throw new Error(`Unsupported JOIN type: ${joinType}`);
+ }
+ }
+ // Apply WHERE clause filtering after JOIN (or on the original data if no join)
+ let filteredData = whereClauses.length > 0
+ ? data.filter(row =>
+ whereClauses.every(clause => evaluateCondition(row, clause))
+ )
+ : data;
+
+ let groupResults = filteredData;
+ if (hasAggregateWithoutGroupBy) {
+ // Special handling for queries like 'SELECT COUNT(*) FROM table'
+ const result = {};
+
+ fields.forEach(field => {
+ const match = /(\w+)\((\*|\w+)\)/.exec(field);
+ if (match) {
+ const [, aggFunc, aggField] = match;
+ switch (aggFunc.toUpperCase()) {
+ case 'COUNT':
+ result[field] = filteredData.length;
+ break;
+ case 'SUM':
+ result[field] = filteredData.reduce(
+ (acc, row) => acc + parseFloat(row[aggField]),
+ 0
+ );
+ break;
+ case 'AVG':
+ result[field] =
+ filteredData.reduce(
+ (acc, row) => acc + parseFloat(row[aggField]),
+ 0
+ ) / filteredData.length;
+ break;
+ case 'MIN':
+ result[field] = Math.min(
+ ...filteredData.map(row => parseFloat(row[aggField]))
+ );
+ break;
+ case 'MAX':
+ result[field] = Math.max(
+ ...filteredData.map(row => parseFloat(row[aggField]))
+ );
+ break;
+ // Additional aggregate functions can be handled here
+ }
+ }
+ });
+
+ return [result];
+ // Add more cases here if needed for other aggregates
+ } else if (groupByFields) {
+ groupResults = applyGroupBy(filteredData, groupByFields, fields);
+
+ // Order them by the specified fields
+ let orderedResults = groupResults;
+ if (orderByFields) {
+ orderedResults = groupResults.sort((a, b) => {
+ for (let { fieldName, order } of orderByFields) {
+ if (a[fieldName] < b[fieldName]) return order === 'ASC' ? -1 : 1;
+ if (a[fieldName] > b[fieldName]) return order === 'ASC' ? 1 : -1;
+ }
+ return 0;
+ });
+ }
+ if (limit !== null) {
+ groupResults = groupResults.slice(0, limit);
+ }
+ return groupResults;
+ } else {
+ // Order them by the specified fields
+ let orderedResults = groupResults;
+ if (orderByFields) {
+ orderedResults = groupResults.sort((a, b) => {
+ for (let { fieldName, order } of orderByFields) {
+ if (a[fieldName] < b[fieldName]) return order === 'ASC' ? -1 : 1;
+ if (a[fieldName] > b[fieldName]) return order === 'ASC' ? 1 : -1;
+ }
+ return 0;
+ });
+ }
+
+ // Select the specified fields
+ let finalResults = orderedResults.map(row => {
+ const selectedRow = {};
+ fields.forEach(field => {
+ // Assuming 'field' is just the column name without table prefix
+ selectedRow[field] = row[field];
+ });
+ return selectedRow;
+ });
+
+ // Remove duplicates if specified
+ let distinctResults = finalResults;
+ if (isDistinct) {
+ distinctResults = [
+ ...new Map(
+ finalResults.map(item => [
+ fields.map(field => item[field]).join('|'),
+ item,
+ ])
+ ).values(),
+ ];
+ }
+
+ let limitResults = distinctResults;
+ if (limit !== null) {
+ limitResults = distinctResults.slice(0, limit);
+ }
+
+ return limitResults;
+ }
+ } catch (error) {
+ throw new Error(`Error executing query: ${error.message}`);
+ }
+}
+
+async function executeINSERTQuery(query) {
+ console.log(parseInsertQuery(query));
+ const { table, columns, values } = parseInsertQuery(query);
+ const data = await readCSV(`${table}.csv`);
+
+ // Create a new row object
+ const newRow = {};
+ columns.forEach((column, index) => {
+ // Remove single quotes from the values
+ let value = values[index];
+ if (value.startsWith("'") && value.endsWith("'")) {
+ value = value.substring(1, value.length - 1);
+ }
+ newRow[column] = value;
+ });
+
+ // Add the new row to the data
+ data.push(newRow);
+
+ // Save the updated data back to the CSV file
+ await writeCSV(`${table}.csv`, data); // Implement writeCSV function
+
+ return { message: 'Row inserted successfully.' };
+}
+
+async function executeDELETEQuery(query) {
+ const { table, whereClauses } = parseDeleteQuery(query);
+ let data = await readCSV(`${table}.csv`);
+
+ if (whereClauses.length > 0) {
+ // Filter out the rows that meet the where clause conditions
+ data = data.filter(
+ row => !whereClauses.every(clause => evaluateCondition(row, clause))
+ );
+ } else {
+ // If no where clause, clear the entire table
+ data = [];
+ }
+
+ // Save the updated data back to the CSV file
+ await writeCSV(`${table}.csv`, data);
+
+ return { message: 'Rows deleted successfully.' };
+}
+
+module.exports = { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery };
\ No newline at end of file
diff --git a/src/queryParser.js b/src/queryParser.js
index 26846dfce..95bd0245d 100644
--- a/src/queryParser.js
+++ b/src/queryParser.js
@@ -1,74 +1,192 @@
-function parseQuery(query) {
- // First, let's trim the query to remove any leading/trailing whitespaces
- query = query.trim();
-
- // Initialize variables for different parts of the query
- let selectPart, fromPart;
-
- // Split the query at the WHERE clause if it exists
- const whereSplit = query.split(/\sWHERE\s/i);
- query = whereSplit[0]; // Everything before WHERE clause
-
- // WHERE clause is the second part after splitting, if it exists
- const whereClause = whereSplit.length > 1 ? whereSplit[1].trim() : null;
-
- // Split the remaining query at the JOIN clause if it exists
- const joinSplit = query.split(/\sINNER JOIN\s/i);
- selectPart = joinSplit[0].trim(); // Everything before JOIN clause
-
- // JOIN clause is the second part after splitting, if it exists
- const joinPart = joinSplit.length > 1 ? joinSplit[1].trim() : null;
-
- // Parse the SELECT part
- const selectRegex = /^SELECT\s(.+?)\sFROM\s(.+)/i;
- const selectMatch = selectPart.match(selectRegex);
- if (!selectMatch) {
- throw new Error('Invalid SELECT format');
+/*
+Creating a Query Parser which can parse SQL `SELECT` Queries only.
+// */
+function parseSelectQuery (query) {
+ try {
+ // Trim the query to remove any leading/trailing whitespaces
+ query = query.trim ();
+
+ // Initialize distinct flag
+ let isDistinct = false;
+
+ // Check for DISTINCT keyword and update the query
+ if (query.toUpperCase ().includes ('SELECT DISTINCT')) {
+ isDistinct = true;
+ query = query.replace ('SELECT DISTINCT', 'SELECT');
+ }
+
+ // Updated regex to capture LIMIT clause and remove it for further processing
+ const limitRegex = /\sLIMIT\s(\d+)/i;
+ const limitMatch = query.match (limitRegex);
+
+ let limit = null;
+ if (limitMatch) {
+ limit = parseInt (limitMatch[1], 10);
+ query = query.replace (limitRegex, ''); // Remove LIMIT clause
+ }
+
+ // Process ORDER BY clause and remove it for further processing
+ const orderByRegex = /\sORDER BY\s(.+)/i;
+ const orderByMatch = query.match (orderByRegex);
+ let orderByFields = null;
+ if (orderByMatch) {
+ orderByFields = orderByMatch[1].split (',').map (field => {
+ const [fieldName, order] = field.trim ().split (/\s+/);
+ return {fieldName, order: order ? order.toUpperCase () : 'ASC'};
+ });
+ query = query.replace (orderByRegex, '');
+ }
+
+ // Process GROUP BY clause and remove it for further processing
+ const groupByRegex = /\sGROUP BY\s(.+)/i;
+ const groupByMatch = query.match (groupByRegex);
+ let groupByFields = null;
+ if (groupByMatch) {
+ groupByFields = groupByMatch[1].split (',').map (field => field.trim ());
+ query = query.replace (groupByRegex, '');
+ }
+
+ // Process WHERE clause
+ const whereSplit = query.split (/\sWHERE\s/i);
+ const queryWithoutWhere = whereSplit[0]; // Everything before WHERE clause
+ const whereClause = whereSplit.length > 1 ? whereSplit[1].trim () : null;
+
+ // Process JOIN clause
+ const joinSplit = queryWithoutWhere.split (/\s(INNER|LEFT|RIGHT) JOIN\s/i);
+ const selectPart = joinSplit[0].trim (); // Everything before JOIN clause
+
+ // Extract JOIN information
+ const {joinType, joinTable, joinCondition} = parseJoinClause (
+ queryWithoutWhere
+ );
+
+ // Parse SELECT part
+ const selectRegex = /^SELECT\s(.+?)\sFROM\s(.+)/i;
+ const selectMatch = selectPart.match (selectRegex);
+ if (!selectMatch) {
+ throw new Error ('Invalid SELECT format');
+ }
+ const [, fields, table] = selectMatch;
+
+ // Parse WHERE part if it exists
+ let whereClauses = [];
+ if (whereClause) {
+ whereClauses = parseWhereClause (whereClause);
+ }
+
+ // Check for aggregate functions without GROUP BY
+ const hasAggregateWithoutGroupBy = checkAggregateWithoutGroupBy (
+ query,
+ groupByFields
+ );
+
+ return {
+ fields: fields.split (',').map (field => field.trim ()),
+ table: table.trim (),
+ whereClauses,
+ joinType,
+ joinTable,
+ joinCondition,
+ groupByFields,
+ orderByFields,
+ hasAggregateWithoutGroupBy,
+ limit,
+ isDistinct,
+ };
+ } catch (error) {
+ throw new Error (`Query parsing error: ${error.message}`);
}
-
- const [, fields, table] = selectMatch;
-
- // Parse the JOIN part if it exists
- let joinTable = null, joinCondition = null;
- if (joinPart) {
- const joinRegex = /^(.+?)\sON\s([\w.]+)\s*=\s*([\w.]+)/i;
- const joinMatch = joinPart.match(joinRegex);
- if (!joinMatch) {
- throw new Error('Invalid JOIN format');
- }
-
- joinTable = joinMatch[1].trim();
- joinCondition = {
- left: joinMatch[2].trim(),
- right: joinMatch[3].trim()
+ }
+
+ function checkAggregateWithoutGroupBy (query, groupByFields) {
+ const aggregateFunctionRegex = /(\bCOUNT\b|\bAVG\b|\bSUM\b|\bMIN\b|\bMAX\b)\s*\(\s*(\*|\w+)\s*\)/i;
+ return aggregateFunctionRegex.test (query) && !groupByFields;
+ }
+
+ function parseWhereClause (whereString) {
+ const conditionRegex = /(.*?)(=|!=|>=|<=|>|<)(.*)/;
+ return whereString.split (/ AND | OR /i).map (conditionString => {
+ if (conditionString.includes (' LIKE ')) {
+ const [field, pattern] = conditionString.split (/\sLIKE\s/i);
+ return {
+ field: field.trim (),
+ operator: 'LIKE',
+ value: pattern.trim ().replace (/^'(.*)'$/, '$1'),
};
+ } else {
+ const match = conditionString.match (conditionRegex);
+ if (match) {
+ const [, field, operator, value] = match;
+ return {field: field.trim (), operator, value: value.trim ()};
+ }
+ throw new Error ('Invalid WHERE clause format');
+ }
+ });
+ }
+
+ function parseJoinClause (query) {
+ const joinRegex = /\s(INNER|LEFT|RIGHT) JOIN\s(.+?)\sON\s([\w.]+)\s*=\s*([\w.]+)/i;
+ const joinMatch = query.match (joinRegex);
+
+ if (joinMatch) {
+ return {
+ joinType: joinMatch[1].trim (),
+ joinTable: joinMatch[2].trim (),
+ joinCondition: {
+ left: joinMatch[3].trim (),
+ right: joinMatch[4].trim (),
+ },
+ };
+ }
+
+ return {
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ };
+ }
+
+ function parseInsertQuery (query) {
+ const insertRegex = /INSERT INTO (\w+)\s\((.+)\)\sVALUES\s\((.+)\)/i;
+ const match = query.match (insertRegex);
+
+ if (!match) {
+ throw new Error ('Invalid INSERT INTO syntax.');
}
-
- // Parse the WHERE part if it exists
+
+ const [, table, columns, values] = match;
+ return {
+ type: 'INSERT',
+ table: table.trim (),
+ columns: columns.split (',').map (column => column.trim ()),
+ values: values.split (',').map (value => value.trim ()),
+ };
+ }
+
+ function parseDeleteQuery (query) {
+ const deleteRegex = /DELETE FROM (\w+)( WHERE (.*))?/i;
+ const match = query.match (deleteRegex);
+
+ if (!match) {
+ throw new Error ('Invalid DELETE syntax.');
+ }
+
+ const [, table, , whereString] = match;
let whereClauses = [];
- if (whereClause) {
- whereClauses = parseWhereClause(whereClause);
+ if (whereString) {
+ whereClauses = parseWhereClause (whereString);
}
-
+
return {
- fields: fields.split(',').map(field => field.trim()),
- table: table.trim(),
- whereClauses,
- joinTable,
- joinCondition
+ type: 'DELETE',
+ table: table.trim (),
+ whereClauses,
};
-}
-
-function parseWhereClause(whereString) {
- const conditionRegex = /(.*?)(=|!=|>|<|>=|<=)(.*)/;
- return whereString.split(/ AND | OR /i).map(conditionString => {
- const match = conditionString.match(conditionRegex);
- if (match) {
- const [, field, operator, value] = match;
- return { field: field.trim(), operator, value: value.trim() };
- }
- throw new Error('Invalid WHERE clause format');
- });
-}
-
-module.exports = parseQuery;
\ No newline at end of file
+ }
+
+ module.exports = {
+ parseSelectQuery,
+ parseJoinClause,
+ parseInsertQuery,
+ parseDeleteQuery,
+ };
\ No newline at end of file
diff --git a/student.csv b/student.csv
index 9e7a9fa25..e9c960121 100644
--- a/student.csv
+++ b/student.csv
@@ -1,4 +1,5 @@
id,name,age
1,John,30
2,Jane,25
-3,Bob,22
\ No newline at end of file
+3,Bob,22
+4,Alice,24
\ No newline at end of file
From 79f2538c221813e30288efeb72031869d9dd01bd Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sat, 4 May 2024 23:10:44 +0530
Subject: [PATCH 14/15] assignment finished with all test cases passed
---
src/cli.js | 116 ++++---
src/csvReader.js | 57 ++--
src/index.js | 32 +-
src/queryExecutor.js | 165 +++------
src/queryParser.js | 315 +++++++++---------
tests/step-02/index.test.js | 6 +-
tests/step-03/index.test.js | 24 +-
tests/step-04/index.test.js | 27 +-
tests/step-05/index.test.js | 52 ++-
tests/step-06/index.test.js | 72 ++--
tests/step-07/index.test.js | 81 +++--
tests/step-08/index.test.js | 65 ++--
tests/step-09/index.test.js | 54 ++-
tests/step-10/index.test.js | 114 +++++--
tests/step-11/index.test.js | 126 ++++---
tests/step-12/index.test.js | 104 +++---
tests/step-13/index.test.js | 104 +++---
tests/step-14/index.test.js | 46 +--
tests/step-15/index.test.js | 46 +--
tests/step-16/index.test.js | 46 +--
tests/step-17/index.test.js | 2 +-
tests/step-17/insertExecuter.test.js | 3 +-
tests/step-18/deleteExecutor.test.js | 2 +-
tests/step-18/index.test.js | 2 +-
tests/step-18/insertExecuter.test.js | 2 +-
...t.js_344b632c9c4863f3843be516d9be4761.prob | 1 +
tests/step-19/deleteExecutor.test.js | 2 +-
tests/step-19/index.test.js | 2 +-
tests/step-19/insertExecuter.test.js | 89 +++--
29 files changed, 1008 insertions(+), 749 deletions(-)
create mode 100644 tests/step-19/.cph/.insertExecuter.test.js_344b632c9c4863f3843be516d9be4761.prob
diff --git a/src/cli.js b/src/cli.js
index 458a6fe42..6d281e6ea 100644
--- a/src/cli.js
+++ b/src/cli.js
@@ -1,51 +1,89 @@
#!/usr/bin/env node
-const readline = require ('readline');
-const {
- executeSELECTQuery,
- executeINSERTQuery,
- executeDELETEQuery,
-} = require ('./index');
-
-const rl = readline.createInterface ({
- input: process.stdin,
- output: process.stdout,
+const readline = require('readline');
+
+const { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery } = require('./index');
+
+
+
+
+const rl = readline.createInterface({
+
+ input: process.stdin,
+
+ output: process.stdout
+
});
-rl.setPrompt ('SQL> ');
-console.log (
- 'SQL Query Engine CLI. Enter your SQL commands, or type "exit" to quit.'
-);
-rl.prompt ();
-rl
- .on ('line', async line => {
- if (line.toLowerCase () === 'exit') {
- rl.close ();
- return;
+
+rl.setPrompt('SQL> ');
+
+console.log('SQL Query Engine CLI. Enter your SQL commands, or type "exit" to quit.');
+
+
+
+
+rl.prompt();
+
+
+
+
+rl.on('line', async (line) => {
+
+ if (line.toLowerCase() === 'exit') {
+
+ rl.close();
+
+ return;
+
}
+
+
+
try {
- if (line.toLowerCase ().startsWith ('select')) {
- const result = await executeSELECTQuery (line);
- console.log ('Result:', result);
- } else if (line.toLowerCase ().startsWith ('insert into')) {
- const result = await executeINSERTQuery (line);
- console.log (result.message);
- } else if (line.toLowerCase ().startsWith ('delete from')) {
- const result = await executeDELETEQuery (line);
- console.log (result.message);
- } else {
- console.log ('Unsupported command');
- }
+
+ if (line.toLowerCase().startsWith('select')) {
+
+ const result = await executeSELECTQuery(line);
+
+ console.log('Result:', result);
+
+ } else if (line.toLowerCase().startsWith('insert into')) {
+
+ const result = await executeINSERTQuery(line);
+
+ console.log(result.message);
+
+ } else if (line.toLowerCase().startsWith('delete from')) {
+
+ const result = await executeDELETEQuery(line);
+
+ console.log(result.message);
+
+ } else {
+
+ console.log('Unsupported command');
+
+ }
+
} catch (error) {
- console.error ('Error:', error.message);
+
+ console.error('Error:', error.message);
+
}
- rl.prompt ();
- })
- .on ('close', () => {
- console.log ('Exiting SQL CLI');
- process.exit (0);
- });
\ No newline at end of file
+
+
+
+ rl.prompt();
+
+}).on('close', () => {
+
+ console.log('Exiting SQL CLI');
+
+ process.exit(0);
+
+});
\ No newline at end of file
diff --git a/src/csvReader.js b/src/csvReader.js
index 20ecfd130..1296d8a25 100644
--- a/src/csvReader.js
+++ b/src/csvReader.js
@@ -1,27 +1,42 @@
-const fs = require ('fs');
-const csv = require ('csv-parser');
-const {parse} = require ('json2csv');
+const fs = require('fs');
+const csv = require('csv-parser');
+const { parse } = require('json2csv');
-function readCSV (filePath) {
- const results = [];
+// function readCSV(filePath) {
+// const results = [];
- return new Promise ((resolve, reject) => {
- fs
- .createReadStream (filePath)
- .pipe (csv ())
- .on ('data', data => results.push (data))
- .on ('end', () => {
- resolve (results);
- })
- .on ('error', error => {
- reject (error);
- });
- });
+// return new Promise((resolve, reject) => {
+// fs.createReadStream(filePath)
+// .pipe(csv())
+// .on('data', (data) => results.push(data))
+// .on('end', () => {
+// resolve(results);
+// })
+// .on('error', (error) => {
+// reject(error);
+// });
+// });
+// }
+function readCSV(filePath) {
+ const results = [];
+ return new Promise((resolve, reject) => {
+ fs.createReadStream(filePath)
+ .pipe(csv())
+ .on('data', (data) => {
+ results.push(data)
+ })
+ .on('end', () => {
+ resolve(results);
+ })
+ .on('error', (error) => {
+ reject(error);
+ });
+ });
}
-async function writeCSV (filename, data) {
- const csv = parse (data);
- fs.writeFileSync (filename, csv);
+async function writeCSV(filename, data) {
+ const csv = parse(data);
+ fs.writeFileSync(filename, csv);
}
-module.exports = {readCSV, writeCSV};
\ No newline at end of file
+module.exports = { readCSV, writeCSV };
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 9cbe0d228..37946433b 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,22 +1,14 @@
-const {readCSV, writeCSV} = require ('./csvReader');
-const {
- parseSelectQuery,
- parseInsertQuery,
- parseDeleteQuery,
-} = require ('./queryParser');
-const {
- executeSELECTQuery,
- executeINSERTQuery,
- executeDELETEQuery,
-} = require ('./queryExecuter');
+const { readCSV, writeCSV } = require('./csvReader');
+const { parseSelectQuery, parseInsertQuery, parseDeleteQuery } = require('./queryParser');
+const { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery } = require('./queryExecuter');
module.exports = {
- readCSV,
- writeCSV,
- executeSELECTQuery,
- executeINSERTQuery,
- executeDELETEQuery,
- parseSelectQuery,
- parseInsertQuery,
- parseDeleteQuery,
-};
\ No newline at end of file
+ readCSV,
+ writeCSV,
+ executeSELECTQuery,
+ executeINSERTQuery,
+ executeDELETEQuery,
+ parseSelectQuery,
+ parseInsertQuery,
+ parseDeleteQuery
+}
\ No newline at end of file
diff --git a/src/queryExecutor.js b/src/queryExecutor.js
index 02d89e3ec..85681f54b 100644
--- a/src/queryExecutor.js
+++ b/src/queryExecutor.js
@@ -1,8 +1,4 @@
-const {
- parseSelectQuery,
- parseInsertQuery,
- parseDeleteQuery,
-} = require('./queryParser');
+const { parseSelectQuery, parseInsertQuery, parseDeleteQuery } = require('./queryParser');
const { readCSV, writeCSV } = require('./csvReader');
function performInnerJoin(data, joinData, joinCondition, fields, table) {
@@ -16,9 +12,7 @@ function performInnerJoin(data, joinData, joinCondition, fields, table) {
.map(joinRow => {
return fields.reduce((acc, field) => {
const [tableName, fieldName] = field.split('.');
- acc[field] = tableName === table
- ? mainRow[fieldName]
- : joinRow[fieldName];
+ acc[field] = tableName === table ? mainRow[fieldName] : joinRow[fieldName];
return acc;
}, {});
});
@@ -37,9 +31,7 @@ function performLeftJoin(data, joinData, joinCondition, fields, table) {
return [createResultRow(mainRow, null, fields, table, true)];
}
- return matchingJoinRows.map(joinRow =>
- createResultRow(mainRow, joinRow, fields, table, true)
- );
+ return matchingJoinRows.map(joinRow => createResultRow(mainRow, joinRow, fields, table, true));
});
}
@@ -50,12 +42,10 @@ function getValueFromRow(row, compoundFieldName) {
function performRightJoin(data, joinData, joinCondition, fields, table) {
// Cache the structure of a main table row (keys only)
- const mainTableRowStructure = data.length > 0
- ? Object.keys(data[0]).reduce((acc, key) => {
- acc[key] = null; // Set all values to null initially
- return acc;
- }, {})
- : {};
+ const mainTableRowStructure = data.length > 0 ? Object.keys(data[0]).reduce((acc, key) => {
+ acc[key] = null; // Set all values to null initially
+ return acc;
+ }, {}) : {};
return joinData.map(joinRow => {
const mainRowMatch = data.find(mainRow => {
@@ -72,13 +62,7 @@ function performRightJoin(data, joinData, joinCondition, fields, table) {
});
}
-function createResultRow(
- mainRow,
- joinRow,
- fields,
- table,
- includeAllMainFields
-) {
+function createResultRow(mainRow, joinRow, fields, table, includeAllMainFields) {
const resultRow = {};
if (includeAllMainFields) {
@@ -91,12 +75,8 @@ function createResultRow(
// Now, add or overwrite with the fields specified in the query
fields.forEach(field => {
- const [tableName, fieldName] = field.includes('.')
- ? field.split('.')
- : [table, field];
- resultRow[field] = tableName === table && mainRow
- ? mainRow[fieldName]
- : joinRow ? joinRow[fieldName] : null;
+ const [tableName, fieldName] = field.includes('.') ? field.split('.') : [table, field];
+ resultRow[field] = tableName === table && mainRow ? mainRow[fieldName] : joinRow ? joinRow[fieldName] : null;
});
return resultRow;
@@ -116,43 +96,32 @@ function evaluateCondition(row, clause) {
if (operator === 'LIKE') {
// Transform SQL LIKE pattern to JavaScript RegExp pattern
- const regexPattern =
- '^' + value.replace(/%/g, '.*').replace(/_/g, '.') + '$';
+ const regexPattern = '^' + value.replace(/%/g, '.*').replace(/_/g, '.') + '$';
const regex = new RegExp(regexPattern, 'i'); // 'i' for case-insensitive matching
return regex.test(row[field]);
}
switch (operator) {
- case '=':
- return rowValue === conditionValue;
- case '!=':
- return rowValue !== conditionValue;
- case '>':
- return rowValue > conditionValue;
- case '<':
- return rowValue < conditionValue;
- case '>=':
- return rowValue >= conditionValue;
- case '<=':
- return rowValue <= conditionValue;
- default:
- throw new Error(`Unsupported operator: ${operator}`);
+ case '=': return rowValue === conditionValue;
+ case '!=': return rowValue !== conditionValue;
+ case '>': return rowValue > conditionValue;
+ case '<': return rowValue < conditionValue;
+ case '>=': return rowValue >= conditionValue;
+ case '<=': return rowValue <= conditionValue;
+ default: throw new Error(`Unsupported operator: ${operator}`);
}
}
// Helper function to parse value based on its apparent type
function parseValue(value) {
+
// Return null or undefined as is
if (value === null || value === undefined) {
return value;
}
// If the value is a string enclosed in single or double quotes, remove them
- if (
- typeof value === 'string' &&
- ((value.startsWith("'") && value.endsWith("'")) ||
- (value.startsWith('"') && value.endsWith('"')))
- ) {
+ if (typeof value === 'string' && ((value.startsWith("'") && value.endsWith("'")) || (value.startsWith('"') && value.endsWith('"')))) {
value = value.substring(1, value.length - 1);
}
@@ -174,9 +143,7 @@ function applyGroupBy(data, groupByFields, aggregateFunctions) {
// Initialize group in results if it doesn't exist
if (!groupResults[groupKey]) {
groupResults[groupKey] = { count: 0, sums: {}, mins: {}, maxes: {} };
- groupByFields.forEach(
- field => (groupResults[groupKey][field] = row[field])
- );
+ groupByFields.forEach(field => groupResults[groupKey][field] = row[field]);
}
// Aggregate calculations
@@ -189,20 +156,13 @@ function applyGroupBy(data, groupByFields, aggregateFunctions) {
switch (aggFunc.toUpperCase()) {
case 'SUM':
- groupResults[groupKey].sums[aggField] =
- (groupResults[groupKey].sums[aggField] || 0) + value;
+ groupResults[groupKey].sums[aggField] = (groupResults[groupKey].sums[aggField] || 0) + value;
break;
case 'MIN':
- groupResults[groupKey].mins[aggField] = Math.min(
- groupResults[groupKey].mins[aggField] || value,
- value
- );
+ groupResults[groupKey].mins[aggField] = Math.min(groupResults[groupKey].mins[aggField] || value, value);
break;
case 'MAX':
- groupResults[groupKey].maxes[aggField] = Math.max(
- groupResults[groupKey].maxes[aggField] || value,
- value
- );
+ groupResults[groupKey].maxes[aggField] = Math.max(groupResults[groupKey].maxes[aggField] || value, value);
break;
// Additional aggregate functions can be added here
}
@@ -214,7 +174,7 @@ function applyGroupBy(data, groupByFields, aggregateFunctions) {
return Object.values(groupResults).map(group => {
// Construct the final grouped object based on required fields
const finalGroup = {};
- groupByFields.forEach(field => (finalGroup[field] = group[field]));
+ groupByFields.forEach(field => finalGroup[field] = group[field]);
aggregateFunctions.forEach(func => {
const match = /(\w+)\((\*|\w+)\)/.exec(func);
if (match) {
@@ -243,19 +203,8 @@ function applyGroupBy(data, groupByFields, aggregateFunctions) {
async function executeSELECTQuery(query) {
try {
- const {
- fields,
- table,
- whereClauses,
- joinType,
- joinTable,
- joinCondition,
- groupByFields,
- hasAggregateWithoutGroupBy,
- orderByFields,
- limit,
- isDistinct,
- } = parseSelectQuery(query);
+
+ const { fields, table, whereClauses, joinType, joinTable, joinCondition, groupByFields, hasAggregateWithoutGroupBy, orderByFields, limit, isDistinct } = parseSelectQuery(query);
let data = await readCSV(`${table}.csv`);
// Perform INNER JOIN if specified
@@ -263,25 +212,13 @@ async function executeSELECTQuery(query) {
const joinData = await readCSV(`${joinTable}.csv`);
switch (joinType.toUpperCase()) {
case 'INNER':
- data = performInnerJoin(
- data,
- joinData,
- joinCondition,
- fields,
- table
- );
+ data = performInnerJoin(data, joinData, joinCondition, fields, table);
break;
case 'LEFT':
data = performLeftJoin(data, joinData, joinCondition, fields, table);
break;
case 'RIGHT':
- data = performRightJoin(
- data,
- joinData,
- joinCondition,
- fields,
- table
- );
+ data = performRightJoin(data, joinData, joinCondition, fields, table);
break;
default:
throw new Error(`Unsupported JOIN type: ${joinType}`);
@@ -289,9 +226,7 @@ async function executeSELECTQuery(query) {
}
// Apply WHERE clause filtering after JOIN (or on the original data if no join)
let filteredData = whereClauses.length > 0
- ? data.filter(row =>
- whereClauses.every(clause => evaluateCondition(row, clause))
- )
+ ? data.filter(row => whereClauses.every(clause => evaluateCondition(row, clause)))
: data;
let groupResults = filteredData;
@@ -308,27 +243,16 @@ async function executeSELECTQuery(query) {
result[field] = filteredData.length;
break;
case 'SUM':
- result[field] = filteredData.reduce(
- (acc, row) => acc + parseFloat(row[aggField]),
- 0
- );
+ result[field] = filteredData.reduce((acc, row) => acc + parseFloat(row[aggField]), 0);
break;
case 'AVG':
- result[field] =
- filteredData.reduce(
- (acc, row) => acc + parseFloat(row[aggField]),
- 0
- ) / filteredData.length;
+ result[field] = filteredData.reduce((acc, row) => acc + parseFloat(row[aggField]), 0) / filteredData.length;
break;
case 'MIN':
- result[field] = Math.min(
- ...filteredData.map(row => parseFloat(row[aggField]))
- );
+ result[field] = Math.min(...filteredData.map(row => parseFloat(row[aggField])));
break;
case 'MAX':
- result[field] = Math.max(
- ...filteredData.map(row => parseFloat(row[aggField]))
- );
+ result[field] = Math.max(...filteredData.map(row => parseFloat(row[aggField])));
break;
// Additional aggregate functions can be handled here
}
@@ -356,6 +280,7 @@ async function executeSELECTQuery(query) {
}
return groupResults;
} else {
+
// Order them by the specified fields
let orderedResults = groupResults;
if (orderByFields) {
@@ -381,14 +306,7 @@ async function executeSELECTQuery(query) {
// Remove duplicates if specified
let distinctResults = finalResults;
if (isDistinct) {
- distinctResults = [
- ...new Map(
- finalResults.map(item => [
- fields.map(field => item[field]).join('|'),
- item,
- ])
- ).values(),
- ];
+ distinctResults = [...new Map(finalResults.map(item => [fields.map(field => item[field]).join('|'), item])).values()];
}
let limitResults = distinctResults;
@@ -397,6 +315,8 @@ async function executeSELECTQuery(query) {
}
return limitResults;
+
+
}
} catch (error) {
throw new Error(`Error executing query: ${error.message}`);
@@ -425,7 +345,7 @@ async function executeINSERTQuery(query) {
// Save the updated data back to the CSV file
await writeCSV(`${table}.csv`, data); // Implement writeCSV function
- return { message: 'Row inserted successfully.' };
+ return { message: "Row inserted successfully." };
}
async function executeDELETEQuery(query) {
@@ -434,9 +354,7 @@ async function executeDELETEQuery(query) {
if (whereClauses.length > 0) {
// Filter out the rows that meet the where clause conditions
- data = data.filter(
- row => !whereClauses.every(clause => evaluateCondition(row, clause))
- );
+ data = data.filter(row => !whereClauses.every(clause => evaluateCondition(row, clause)));
} else {
// If no where clause, clear the entire table
data = [];
@@ -445,7 +363,8 @@ async function executeDELETEQuery(query) {
// Save the updated data back to the CSV file
await writeCSV(`${table}.csv`, data);
- return { message: 'Rows deleted successfully.' };
+ return { message: "Rows deleted successfully." };
}
+
module.exports = { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery };
\ No newline at end of file
diff --git a/src/queryParser.js b/src/queryParser.js
index 95bd0245d..67b94f5d0 100644
--- a/src/queryParser.js
+++ b/src/queryParser.js
@@ -1,192 +1,177 @@
-/*
-Creating a Query Parser which can parse SQL `SELECT` Queries only.
-// */
-function parseSelectQuery (query) {
+function parseSelectQuery(query) {
try {
- // Trim the query to remove any leading/trailing whitespaces
- query = query.trim ();
-
- // Initialize distinct flag
- let isDistinct = false;
-
- // Check for DISTINCT keyword and update the query
- if (query.toUpperCase ().includes ('SELECT DISTINCT')) {
- isDistinct = true;
- query = query.replace ('SELECT DISTINCT', 'SELECT');
- }
-
- // Updated regex to capture LIMIT clause and remove it for further processing
- const limitRegex = /\sLIMIT\s(\d+)/i;
- const limitMatch = query.match (limitRegex);
-
- let limit = null;
- if (limitMatch) {
- limit = parseInt (limitMatch[1], 10);
- query = query.replace (limitRegex, ''); // Remove LIMIT clause
- }
-
- // Process ORDER BY clause and remove it for further processing
- const orderByRegex = /\sORDER BY\s(.+)/i;
- const orderByMatch = query.match (orderByRegex);
- let orderByFields = null;
- if (orderByMatch) {
- orderByFields = orderByMatch[1].split (',').map (field => {
- const [fieldName, order] = field.trim ().split (/\s+/);
- return {fieldName, order: order ? order.toUpperCase () : 'ASC'};
- });
- query = query.replace (orderByRegex, '');
- }
-
- // Process GROUP BY clause and remove it for further processing
- const groupByRegex = /\sGROUP BY\s(.+)/i;
- const groupByMatch = query.match (groupByRegex);
- let groupByFields = null;
- if (groupByMatch) {
- groupByFields = groupByMatch[1].split (',').map (field => field.trim ());
- query = query.replace (groupByRegex, '');
- }
-
- // Process WHERE clause
- const whereSplit = query.split (/\sWHERE\s/i);
- const queryWithoutWhere = whereSplit[0]; // Everything before WHERE clause
- const whereClause = whereSplit.length > 1 ? whereSplit[1].trim () : null;
-
- // Process JOIN clause
- const joinSplit = queryWithoutWhere.split (/\s(INNER|LEFT|RIGHT) JOIN\s/i);
- const selectPart = joinSplit[0].trim (); // Everything before JOIN clause
-
- // Extract JOIN information
- const {joinType, joinTable, joinCondition} = parseJoinClause (
- queryWithoutWhere
- );
-
- // Parse SELECT part
- const selectRegex = /^SELECT\s(.+?)\sFROM\s(.+)/i;
- const selectMatch = selectPart.match (selectRegex);
- if (!selectMatch) {
- throw new Error ('Invalid SELECT format');
- }
- const [, fields, table] = selectMatch;
-
- // Parse WHERE part if it exists
- let whereClauses = [];
- if (whereClause) {
- whereClauses = parseWhereClause (whereClause);
- }
-
- // Check for aggregate functions without GROUP BY
- const hasAggregateWithoutGroupBy = checkAggregateWithoutGroupBy (
- query,
- groupByFields
- );
-
- return {
- fields: fields.split (',').map (field => field.trim ()),
- table: table.trim (),
- whereClauses,
- joinType,
- joinTable,
- joinCondition,
- groupByFields,
- orderByFields,
- hasAggregateWithoutGroupBy,
- limit,
- isDistinct,
- };
+
+ // Trim the query to remove any leading/trailing whitespaces
+ query = query.trim();
+
+ // Initialize distinct flag
+ let isDistinct = false;
+
+ // Check for DISTINCT keyword and update the query
+ if (query.toUpperCase().includes('SELECT DISTINCT')) {
+ isDistinct = true;
+ query = query.replace('SELECT DISTINCT', 'SELECT');
+ }
+
+ // Updated regex to capture LIMIT clause and remove it for further processing
+ const limitRegex = /\sLIMIT\s(\d+)/i;
+ const limitMatch = query.match(limitRegex);
+
+ let limit = null;
+ if (limitMatch) {
+ limit = parseInt(limitMatch[1], 10);
+ query = query.replace(limitRegex, ''); // Remove LIMIT clause
+ }
+
+ // Process ORDER BY clause and remove it for further processing
+ const orderByRegex = /\sORDER BY\s(.+)/i;
+ const orderByMatch = query.match(orderByRegex);
+ let orderByFields = null;
+ if (orderByMatch) {
+ orderByFields = orderByMatch[1].split(',').map(field => {
+ const [fieldName, order] = field.trim().split(/\s+/);
+ return { fieldName, order: order ? order.toUpperCase() : 'ASC' };
+ });
+ query = query.replace(orderByRegex, '');
+ }
+
+ // Process GROUP BY clause and remove it for further processing
+ const groupByRegex = /\sGROUP BY\s(.+)/i;
+ const groupByMatch = query.match(groupByRegex);
+ let groupByFields = null;
+ if (groupByMatch) {
+ groupByFields = groupByMatch[1].split(',').map(field => field.trim());
+ query = query.replace(groupByRegex, '');
+ }
+
+ // Process WHERE clause
+ const whereSplit = query.split(/\sWHERE\s/i);
+ const queryWithoutWhere = whereSplit[0]; // Everything before WHERE clause
+ const whereClause = whereSplit.length > 1 ? whereSplit[1].trim() : null;
+
+ // Process JOIN clause
+ const joinSplit = queryWithoutWhere.split(/\s(INNER|LEFT|RIGHT) JOIN\s/i);
+ const selectPart = joinSplit[0].trim(); // Everything before JOIN clause
+
+ // Extract JOIN information
+ const { joinType, joinTable, joinCondition } = parseJoinClause(queryWithoutWhere);
+
+ // Parse SELECT part
+ const selectRegex = /^SELECT\s(.+?)\sFROM\s(.+)/i;
+ const selectMatch = selectPart.match(selectRegex);
+ if (!selectMatch) {
+ throw new Error('Invalid SELECT format');
+ }
+ const [, fields, table] = selectMatch;
+
+ // Parse WHERE part if it exists
+ let whereClauses = [];
+ if (whereClause) {
+ whereClauses = parseWhereClause(whereClause);
+ }
+
+ // Check for aggregate functions without GROUP BY
+ const hasAggregateWithoutGroupBy = checkAggregateWithoutGroupBy(query, groupByFields);
+
+ return {
+ fields: fields.split(',').map(field => field.trim()),
+ table: table.trim(),
+ whereClauses,
+ joinType,
+ joinTable,
+ joinCondition,
+ groupByFields,
+ orderByFields,
+ hasAggregateWithoutGroupBy,
+ limit,
+ isDistinct
+ };
} catch (error) {
- throw new Error (`Query parsing error: ${error.message}`);
+ throw new Error(`Query parsing error: ${error.message}`);
}
- }
-
- function checkAggregateWithoutGroupBy (query, groupByFields) {
+}
+
+function checkAggregateWithoutGroupBy(query, groupByFields) {
const aggregateFunctionRegex = /(\bCOUNT\b|\bAVG\b|\bSUM\b|\bMIN\b|\bMAX\b)\s*\(\s*(\*|\w+)\s*\)/i;
- return aggregateFunctionRegex.test (query) && !groupByFields;
- }
-
- function parseWhereClause (whereString) {
+ return aggregateFunctionRegex.test(query) && !groupByFields;
+}
+
+function parseWhereClause(whereString) {
const conditionRegex = /(.*?)(=|!=|>=|<=|>|<)(.*)/;
- return whereString.split (/ AND | OR /i).map (conditionString => {
- if (conditionString.includes (' LIKE ')) {
- const [field, pattern] = conditionString.split (/\sLIKE\s/i);
- return {
- field: field.trim (),
- operator: 'LIKE',
- value: pattern.trim ().replace (/^'(.*)'$/, '$1'),
- };
- } else {
- const match = conditionString.match (conditionRegex);
- if (match) {
- const [, field, operator, value] = match;
- return {field: field.trim (), operator, value: value.trim ()};
+ return whereString.split(/ AND | OR /i).map(conditionString => {
+ if (conditionString.includes(' LIKE ')) {
+ const [field, pattern] = conditionString.split(/\sLIKE\s/i);
+ return { field: field.trim(), operator: 'LIKE', value: pattern.trim().replace(/^'(.*)'$/, '$1') };
+ } else {
+ const match = conditionString.match(conditionRegex);
+ if (match) {
+ const [, field, operator, value] = match;
+ return { field: field.trim(), operator, value: value.trim() };
+ }
+ throw new Error('Invalid WHERE clause format');
}
- throw new Error ('Invalid WHERE clause format');
- }
});
- }
-
- function parseJoinClause (query) {
+}
+
+function parseJoinClause(query) {
const joinRegex = /\s(INNER|LEFT|RIGHT) JOIN\s(.+?)\sON\s([\w.]+)\s*=\s*([\w.]+)/i;
- const joinMatch = query.match (joinRegex);
-
+ const joinMatch = query.match(joinRegex);
+
if (joinMatch) {
- return {
- joinType: joinMatch[1].trim (),
- joinTable: joinMatch[2].trim (),
- joinCondition: {
- left: joinMatch[3].trim (),
- right: joinMatch[4].trim (),
- },
- };
+ return {
+ joinType: joinMatch[1].trim(),
+ joinTable: joinMatch[2].trim(),
+ joinCondition: {
+ left: joinMatch[3].trim(),
+ right: joinMatch[4].trim()
+ }
+ };
}
-
+
return {
- joinType: null,
- joinTable: null,
- joinCondition: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null
};
- }
-
- function parseInsertQuery (query) {
+}
+
+function parseInsertQuery(query) {
const insertRegex = /INSERT INTO (\w+)\s\((.+)\)\sVALUES\s\((.+)\)/i;
- const match = query.match (insertRegex);
-
+ const match = query.match(insertRegex);
+
if (!match) {
- throw new Error ('Invalid INSERT INTO syntax.');
+ throw new Error("Invalid INSERT INTO syntax.");
}
-
+
const [, table, columns, values] = match;
return {
- type: 'INSERT',
- table: table.trim (),
- columns: columns.split (',').map (column => column.trim ()),
- values: values.split (',').map (value => value.trim ()),
+ type: 'INSERT',
+ table: table.trim(),
+ columns: columns.split(',').map(column => column.trim()),
+ values: values.split(',').map(value => value.trim())
};
- }
-
- function parseDeleteQuery (query) {
+}
+
+function parseDeleteQuery(query) {
const deleteRegex = /DELETE FROM (\w+)( WHERE (.*))?/i;
- const match = query.match (deleteRegex);
-
+ const match = query.match(deleteRegex);
+
if (!match) {
- throw new Error ('Invalid DELETE syntax.');
+ throw new Error("Invalid DELETE syntax.");
}
-
+
const [, table, , whereString] = match;
let whereClauses = [];
if (whereString) {
- whereClauses = parseWhereClause (whereString);
+ whereClauses = parseWhereClause(whereString);
}
-
+
return {
- type: 'DELETE',
- table: table.trim (),
- whereClauses,
+ type: 'DELETE',
+ table: table.trim(),
+ whereClauses
};
- }
-
- module.exports = {
- parseSelectQuery,
- parseJoinClause,
- parseInsertQuery,
- parseDeleteQuery,
- };
\ No newline at end of file
+}
+
+
+module.exports = { parseSelectQuery, parseJoinClause, parseInsertQuery, parseDeleteQuery };
\ No newline at end of file
diff --git a/tests/step-02/index.test.js b/tests/step-02/index.test.js
index a5467ee48..59a3322e8 100644
--- a/tests/step-02/index.test.js
+++ b/tests/step-02/index.test.js
@@ -1,9 +1,9 @@
-const readCSV = require('../../src/csvReader');
+const {readCSV} = require('../../src/csvReader');
test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
+ const data = await readCSV('./student.csv');
expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
+ expect(data.length).toBe(4);
expect(data[0].name).toBe('John');
expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
});
\ No newline at end of file
diff --git a/tests/step-03/index.test.js b/tests/step-03/index.test.js
index 9145ad3e4..fcb733a0b 100644
--- a/tests/step-03/index.test.js
+++ b/tests/step-03/index.test.js
@@ -1,19 +1,29 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
+
+const {readCSV} = require('../../src/csvReader');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
+ const data = await readCSV('./student.csv');
expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
+ expect(data.length).toBe(4);
expect(data[0].name).toBe('John');
expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
});
test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample'
+ table: 'student',
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
\ No newline at end of file
diff --git a/tests/step-04/index.test.js b/tests/step-04/index.test.js
index bc353dd3d..51e8cfd7d 100644
--- a/tests/step-04/index.test.js
+++ b/tests/step-04/index.test.js
@@ -1,26 +1,35 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
+ const data = await readCSV('./student.csv');
expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
+ expect(data.length).toBe(4);
expect(data[0].name).toBe('John');
expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
});
test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample'
+ table: 'student',
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM sample';
+ const query = 'SELECT id, name FROM student';
const result = await executeSELECTQuery(query);
expect(result.length).toBeGreaterThan(0);
expect(result[0]).toHaveProperty('id');
diff --git a/tests/step-05/index.test.js b/tests/step-05/index.test.js
index 66a77c061..8522a0db7 100644
--- a/tests/step-05/index.test.js
+++ b/tests/step-05/index.test.js
@@ -1,27 +1,35 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
+ const data = await readCSV('./student.csv');
expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
+ expect(data.length).toBe(4);
expect(data[0].name).toBe('John');
expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
});
test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample',
- whereClause: null
+ table: 'student',
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM sample';
+ const query = 'SELECT id, name FROM student';
const result = await executeSELECTQuery(query);
expect(result.length).toBeGreaterThan(0);
expect(result[0]).toHaveProperty('id');
@@ -29,19 +37,29 @@ test('Execute SQL Query', async () => {
expect(result[0]).not.toHaveProperty('age');
expect(result[0]).toEqual({ id: '1', name: 'John' });
});
-
test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student WHERE age = 25';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample',
- whereClause: 'age = 25'
+ table: 'student',
+ whereClauses: [{
+ "field": "age",
+ "operator": "=",
+ "value": "25",
+ }],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
-
test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
+ const query = 'SELECT id, name FROM student WHERE age = 25';
const result = await executeSELECTQuery(query);
expect(result.length).toBe(1);
expect(result[0]).toHaveProperty('id');
diff --git a/tests/step-06/index.test.js b/tests/step-06/index.test.js
index 2e2ef6416..fe79fabba 100644
--- a/tests/step-06/index.test.js
+++ b/tests/step-06/index.test.js
@@ -1,27 +1,35 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
+ const data = await readCSV('./student.csv');
expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
+ expect(data.length).toBe(4);
expect(data[0].name).toBe('John');
expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
});
test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample',
- whereClauses: []
+ table: 'student',
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM sample';
+ const query = 'SELECT id, name FROM student';
const result = await executeSELECTQuery(query);
expect(result.length).toBeGreaterThan(0);
expect(result[0]).toHaveProperty('id');
@@ -29,23 +37,29 @@ test('Execute SQL Query', async () => {
expect(result[0]).not.toHaveProperty('age');
expect(result[0]).toEqual({ id: '1', name: 'John' });
});
-
test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student WHERE age = 25';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample',
+ table: 'student',
whereClauses: [{
- field: "age",
- operator: "=",
- value: "25",
+ "field": "age",
+ "operator": "=",
+ "value": "25",
}],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
-
test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
+ const query = 'SELECT id, name FROM student WHERE age = 25';
const result = await executeSELECTQuery(query);
expect(result.length).toBe(1);
expect(result[0]).toHaveProperty('id');
@@ -54,11 +68,11 @@ test('Execute SQL Query with WHERE Clause', async () => {
});
test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample',
+ table: 'student',
whereClauses: [{
"field": "age",
"operator": "=",
@@ -67,12 +81,20 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
"field": "name",
"operator": "=",
"value": "John",
- }]
+ }],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
-test('Execute SQL Query with Multiple WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
+test('Execute SQL Query with Complex WHERE Clause', async () => {
+ const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
const result = await executeSELECTQuery(query);
expect(result.length).toBe(1);
expect(result[0]).toEqual({ id: '1', name: 'John' });
diff --git a/tests/step-07/index.test.js b/tests/step-07/index.test.js
index ee0ebed5e..5faa49133 100644
--- a/tests/step-07/index.test.js
+++ b/tests/step-07/index.test.js
@@ -1,27 +1,35 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
+ const data = await readCSV('./student.csv');
expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
+ expect(data.length).toBe(4);
expect(data[0].name).toBe('John');
expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
});
test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample',
- whereClauses: []
+ table: 'student',
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM sample';
+ const query = 'SELECT id, name FROM student';
const result = await executeSELECTQuery(query);
expect(result.length).toBeGreaterThan(0);
expect(result[0]).toHaveProperty('id');
@@ -29,23 +37,29 @@ test('Execute SQL Query', async () => {
expect(result[0]).not.toHaveProperty('age');
expect(result[0]).toEqual({ id: '1', name: 'John' });
});
-
test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student WHERE age = 25';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample',
+ table: 'student',
whereClauses: [{
- field: "age",
- operator: "=",
- value: "25",
+ "field": "age",
+ "operator": "=",
+ "value": "25",
}],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
-
test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
+ const query = 'SELECT id, name FROM student WHERE age = 25';
const result = await executeSELECTQuery(query);
expect(result.length).toBe(1);
expect(result[0]).toHaveProperty('id');
@@ -54,11 +68,11 @@ test('Execute SQL Query with WHERE Clause', async () => {
});
test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
- table: 'sample',
+ table: 'student',
whereClauses: [{
"field": "age",
"operator": "=",
@@ -67,27 +81,34 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
"field": "name",
"operator": "=",
"value": "John",
- }]
+ }],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
-test('Execute SQL Query with Multiple WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
+test('Execute SQL Query with Complex WHERE Clause', async () => {
+ const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
const result = await executeSELECTQuery(query);
expect(result.length).toBe(1);
expect(result[0]).toEqual({ id: '1', name: 'John' });
});
-
test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM sample WHERE age > 22';
+ const queryWithGT = 'SELECT id FROM student WHERE age > 22';
const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
+ expect(result.length).toEqual(3);
expect(result[0]).toHaveProperty('id');
});
test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM sample WHERE age != 25';
+ const queryWithGT = 'SELECT name FROM student WHERE age != 25';
const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
+ expect(result.length).toEqual(3);
expect(result[0]).toHaveProperty('name');
});
\ No newline at end of file
diff --git a/tests/step-08/index.test.js b/tests/step-08/index.test.js
index aab1467e6..93e1799b0 100644
--- a/tests/step-08/index.test.js
+++ b/tests/step-08/index.test.js
@@ -1,24 +1,30 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
const data = await readCSV('./student.csv');
expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
+ expect(data.length).toBe(4);
expect(data[0].name).toBe('John');
expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
});
test('Parse SQL Query', () => {
const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
whereClauses: [],
joinCondition: null,
- joinTable: null
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
@@ -31,10 +37,9 @@ test('Execute SQL Query', async () => {
expect(result[0]).not.toHaveProperty('age');
expect(result[0]).toEqual({ id: '1', name: 'John' });
});
-
test('Parse SQL Query with WHERE Clause', () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -44,10 +49,15 @@ test('Parse SQL Query with WHERE Clause', () => {
"value": "25",
}],
joinCondition: null,
- joinTable: null
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
-
test('Execute SQL Query with WHERE Clause', async () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
const result = await executeSELECTQuery(query);
@@ -59,7 +69,7 @@ test('Execute SQL Query with WHERE Clause', async () => {
test('Parse SQL Query with Multiple WHERE Clauses', () => {
const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -73,7 +83,13 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
"value": "John",
}],
joinCondition: null,
- joinTable: null
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
@@ -83,42 +99,53 @@ test('Execute SQL Query with Complex WHERE Clause', async () => {
expect(result.length).toBe(1);
expect(result[0]).toEqual({ id: '1', name: 'John' });
});
-
test('Execute SQL Query with Greater Than', async () => {
const queryWithGT = 'SELECT id FROM student WHERE age > 22';
const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
+ expect(result.length).toEqual(3);
expect(result[0]).toHaveProperty('id');
});
test('Execute SQL Query with Not Equal to', async () => {
const queryWithGT = 'SELECT name FROM student WHERE age != 25';
const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
+ expect(result.length).toEqual(3);
expect(result[0]).toHaveProperty('name');
});
test('Parse SQL Query with INNER JOIN', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
whereClauses: [],
joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' }
+ joinType: "INNER",
+ joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
});
test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' }
+ joinType: "INNER",
+ joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
});
diff --git a/tests/step-09/index.test.js b/tests/step-09/index.test.js
index aaf711f5a..02e6cdb86 100644
--- a/tests/step-09/index.test.js
+++ b/tests/step-09/index.test.js
@@ -1,6 +1,6 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
const data = await readCSV('./student.csv');
@@ -12,14 +12,19 @@ test('Read CSV File', async () => {
test('Parse SQL Query', () => {
const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
whereClauses: [],
joinCondition: null,
joinTable: null,
- joinType: null
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
@@ -32,10 +37,9 @@ test('Execute SQL Query', async () => {
expect(result[0]).not.toHaveProperty('age');
expect(result[0]).toEqual({ id: '1', name: 'John' });
});
-
test('Parse SQL Query with WHERE Clause', () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -46,10 +50,14 @@ test('Parse SQL Query with WHERE Clause', () => {
}],
joinCondition: null,
joinTable: null,
- joinType: null
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
-
test('Execute SQL Query with WHERE Clause', async () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
const result = await executeSELECTQuery(query);
@@ -61,7 +69,7 @@ test('Execute SQL Query with WHERE Clause', async () => {
test('Parse SQL Query with Multiple WHERE Clauses', () => {
const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -76,7 +84,12 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
}],
joinCondition: null,
joinTable: null,
- joinType: null
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
@@ -86,7 +99,6 @@ test('Execute SQL Query with Complex WHERE Clause', async () => {
expect(result.length).toBe(1);
expect(result[0]).toEqual({ id: '1', name: 'John' });
});
-
test('Execute SQL Query with Greater Than', async () => {
const queryWithGT = 'SELECT id FROM student WHERE age > 22';
const result = await executeSELECTQuery(queryWithGT);
@@ -103,27 +115,37 @@ test('Execute SQL Query with Not Equal to', async () => {
test('Parse SQL Query with INNER JOIN', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
whereClauses: [],
joinTable: 'enrollment',
+ joinType: "INNER",
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- joinType: 'INNER'
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
});
test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
joinTable: 'enrollment',
+ joinType: "INNER",
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- joinType: 'INNER'
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
});
diff --git a/tests/step-10/index.test.js b/tests/step-10/index.test.js
index 5e118eda5..2b9ef2e73 100644
--- a/tests/step-10/index.test.js
+++ b/tests/step-10/index.test.js
@@ -1,6 +1,6 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
const data = await readCSV('./student.csv');
@@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => {
test('Parse SQL Query', () => {
const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -268,12 +268,15 @@ test('Parse SQL Query', () => {
joinType: null,
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with WHERE Clause', () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -287,12 +290,15 @@ test('Parse SQL Query with WHERE Clause', () => {
joinType: null,
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with Multiple WHERE Clauses', () => {
const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -310,12 +316,15 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
joinType: null,
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with INNER JOIN', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -325,12 +334,15 @@ test('Parse SQL Query with INNER JOIN', async () => {
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
});
test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -340,6 +352,9 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
});
@@ -387,7 +402,7 @@ test('Returns null for queries without JOIN', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -397,12 +412,15 @@ test('Parse LEFT Join Query Completely', () => {
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
})
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -412,12 +430,15 @@ test('Parse LEFT Join Query Completely', () => {
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
})
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -427,12 +448,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl
"whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -442,12 +466,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl
"whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -457,12 +484,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab
"whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -472,13 +502,16 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab
"whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
groupByFields: null,
hasAggregateWithoutGroupBy: false,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse COUNT Aggregate Query', () => {
const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['COUNT(*)'],
table: 'student',
@@ -488,13 +521,16 @@ test('Parse COUNT Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SUM Aggregate Query', () => {
const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['SUM(age)'],
table: 'student',
@@ -504,12 +540,15 @@ test('Parse SUM Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse AVG Aggregate Query', () => {
const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['AVG(age)'],
table: 'student',
@@ -519,12 +558,15 @@ test('Parse AVG Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse MIN Aggregate Query', () => {
const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MIN(age)'],
table: 'student',
@@ -534,12 +576,15 @@ test('Parse MIN Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse MAX Aggregate Query', () => {
const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MAX(age)'],
table: 'student',
@@ -549,12 +594,15 @@ test('Parse MAX Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse basic GROUP BY query', () => {
const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -563,13 +611,16 @@ test('Parse basic GROUP BY query', () => {
joinType: null,
joinTable: null,
joinCondition: null,
- hasAggregateWithoutGroupBy: false
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with WHERE clause', () => {
const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -578,13 +629,16 @@ test('Parse GROUP BY query with WHERE clause', () => {
joinType: null,
joinTable: null,
joinCondition: null,
- hasAggregateWithoutGroupBy: false
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with multiple fields', () => {
const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student_id', 'course', 'COUNT(*)'],
table: 'enrollment',
@@ -593,13 +647,16 @@ test('Parse GROUP BY query with multiple fields', () => {
joinType: null,
joinTable: null,
joinCondition: null,
- hasAggregateWithoutGroupBy: false
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student.name', 'COUNT(*)'],
table: 'student',
@@ -611,6 +668,9 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
left: 'student.id',
right: 'enrollment.student_id'
},
- hasAggregateWithoutGroupBy: false
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ "limit": null,
+ isDistinct: false,
});
});
\ No newline at end of file
diff --git a/tests/step-11/index.test.js b/tests/step-11/index.test.js
index 1cf5f2def..68f672e72 100644
--- a/tests/step-11/index.test.js
+++ b/tests/step-11/index.test.js
@@ -1,6 +1,6 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
const data = await readCSV('./student.csv');
@@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => {
test('Parse SQL Query', () => {
const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -268,13 +268,15 @@ test('Parse SQL Query', () => {
joinType: null,
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with WHERE Clause', () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -288,13 +290,15 @@ test('Parse SQL Query with WHERE Clause', () => {
joinType: null,
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with Multiple WHERE Clauses', () => {
const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -312,13 +316,15 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
joinType: null,
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with INNER JOIN', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -328,13 +334,15 @@ test('Parse SQL Query with INNER JOIN', async () => {
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
});
test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -344,7 +352,9 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
});
@@ -392,7 +402,7 @@ test('Returns null for queries without JOIN', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -402,13 +412,15 @@ test('Parse LEFT Join Query Completely', () => {
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
})
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -418,13 +430,15 @@ test('Parse LEFT Join Query Completely', () => {
joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
})
})
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -434,13 +448,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl
"whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -450,13 +466,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl
"whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -466,13 +484,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab
"whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -482,14 +502,16 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab
"whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
groupByFields: null,
hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse COUNT Aggregate Query', () => {
const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['COUNT(*)'],
table: 'student',
@@ -499,14 +521,16 @@ test('Parse COUNT Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SUM Aggregate Query', () => {
const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['SUM(age)'],
table: 'student',
@@ -516,13 +540,15 @@ test('Parse SUM Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse AVG Aggregate Query', () => {
const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['AVG(age)'],
table: 'student',
@@ -532,13 +558,15 @@ test('Parse AVG Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse MIN Aggregate Query', () => {
const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MIN(age)'],
table: 'student',
@@ -548,13 +576,15 @@ test('Parse MIN Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse MAX Aggregate Query', () => {
const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MAX(age)'],
table: 'student',
@@ -564,13 +594,15 @@ test('Parse MAX Aggregate Query', () => {
"joinCondition": null,
"joinTable": null,
"joinType": null,
- "orderByFields": null
+ "orderByFields": null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse basic GROUP BY query', () => {
const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -580,13 +612,15 @@ test('Parse basic GROUP BY query', () => {
joinTable: null,
joinCondition: null,
hasAggregateWithoutGroupBy: false,
- orderByFields: null
+ orderByFields: null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with WHERE clause', () => {
const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -596,13 +630,15 @@ test('Parse GROUP BY query with WHERE clause', () => {
joinTable: null,
joinCondition: null,
hasAggregateWithoutGroupBy: false,
- orderByFields: null
+ orderByFields: null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with multiple fields', () => {
const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student_id', 'course', 'COUNT(*)'],
table: 'enrollment',
@@ -612,13 +648,15 @@ test('Parse GROUP BY query with multiple fields', () => {
joinTable: null,
joinCondition: null,
hasAggregateWithoutGroupBy: false,
- orderByFields: null
+ orderByFields: null,
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student.name', 'COUNT(*)'],
table: 'student',
@@ -631,7 +669,9 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
right: 'enrollment.student_id'
},
hasAggregateWithoutGroupBy: false,
- orderByFields: null
+ orderByFields: null,
+ "limit": null,
+ isDistinct: false,
});
});
diff --git a/tests/step-12/index.test.js b/tests/step-12/index.test.js
index d15c77ef5..d6a7a6913 100644
--- a/tests/step-12/index.test.js
+++ b/tests/step-12/index.test.js
@@ -1,6 +1,6 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
const data = await readCSV('./student.csv');
@@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => {
test('Parse SQL Query', () => {
const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -269,13 +269,14 @@ test('Parse SQL Query', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with WHERE Clause', () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -290,13 +291,14 @@ test('Parse SQL Query with WHERE Clause', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with Multiple WHERE Clauses', () => {
const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -315,13 +317,14 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with INNER JOIN', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -332,13 +335,14 @@ test('Parse SQL Query with INNER JOIN', async () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
})
});
test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -349,7 +353,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
})
});
@@ -397,7 +402,7 @@ test('Returns null for queries without JOIN', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -408,13 +413,14 @@ test('Parse LEFT Join Query Completely', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
})
})
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -425,13 +431,14 @@ test('Parse LEFT Join Query Completely', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
})
})
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -442,13 +449,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -459,13 +467,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -476,13 +485,14 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -493,14 +503,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse COUNT Aggregate Query', () => {
const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['COUNT(*)'],
table: 'student',
@@ -511,14 +522,15 @@ test('Parse COUNT Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SUM Aggregate Query', () => {
const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['SUM(age)'],
table: 'student',
@@ -529,13 +541,14 @@ test('Parse SUM Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse AVG Aggregate Query', () => {
const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['AVG(age)'],
table: 'student',
@@ -546,13 +559,14 @@ test('Parse AVG Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse MIN Aggregate Query', () => {
const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MIN(age)'],
table: 'student',
@@ -563,13 +577,14 @@ test('Parse MIN Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse MAX Aggregate Query', () => {
const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MAX(age)'],
table: 'student',
@@ -580,13 +595,14 @@ test('Parse MAX Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse basic GROUP BY query', () => {
const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -597,13 +613,14 @@ test('Parse basic GROUP BY query', () => {
joinCondition: null,
hasAggregateWithoutGroupBy: false,
orderByFields: null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with WHERE clause', () => {
const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -614,13 +631,14 @@ test('Parse GROUP BY query with WHERE clause', () => {
joinCondition: null,
hasAggregateWithoutGroupBy: false,
orderByFields: null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with multiple fields', () => {
const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student_id', 'course', 'COUNT(*)'],
table: 'enrollment',
@@ -631,13 +649,14 @@ test('Parse GROUP BY query with multiple fields', () => {
joinCondition: null,
hasAggregateWithoutGroupBy: false,
orderByFields: null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student.name', 'COUNT(*)'],
table: 'student',
@@ -652,6 +671,7 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
hasAggregateWithoutGroupBy: false,
orderByFields: null,
"limit": null,
+ isDistinct: false,
});
});
diff --git a/tests/step-13/index.test.js b/tests/step-13/index.test.js
index 0797faaba..5fe667f4c 100644
--- a/tests/step-13/index.test.js
+++ b/tests/step-13/index.test.js
@@ -1,6 +1,6 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
const data = await readCSV('./student.csv');
@@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => {
test('Parse SQL Query', () => {
const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -269,13 +269,14 @@ test('Parse SQL Query', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with WHERE Clause', () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -290,13 +291,14 @@ test('Parse SQL Query with WHERE Clause', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with Multiple WHERE Clauses', () => {
const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -315,13 +317,14 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with INNER JOIN', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -332,13 +335,14 @@ test('Parse SQL Query with INNER JOIN', async () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
})
});
test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -349,7 +353,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
})
});
@@ -397,7 +402,7 @@ test('Returns null for queries without JOIN', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -408,13 +413,14 @@ test('Parse LEFT Join Query Completely', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
})
})
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -425,13 +431,14 @@ test('Parse LEFT Join Query Completely', () => {
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
})
})
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -442,13 +449,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -459,13 +467,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -476,13 +485,14 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -493,14 +503,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab
groupByFields: null,
hasAggregateWithoutGroupBy: false,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse COUNT Aggregate Query', () => {
const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['COUNT(*)'],
table: 'student',
@@ -511,14 +522,15 @@ test('Parse COUNT Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse SUM Aggregate Query', () => {
const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['SUM(age)'],
table: 'student',
@@ -529,13 +541,14 @@ test('Parse SUM Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse AVG Aggregate Query', () => {
const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['AVG(age)'],
table: 'student',
@@ -546,13 +559,14 @@ test('Parse AVG Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse MIN Aggregate Query', () => {
const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MIN(age)'],
table: 'student',
@@ -563,13 +577,14 @@ test('Parse MIN Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse MAX Aggregate Query', () => {
const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MAX(age)'],
table: 'student',
@@ -580,13 +595,14 @@ test('Parse MAX Aggregate Query', () => {
"joinTable": null,
"joinType": null,
"orderByFields": null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse basic GROUP BY query', () => {
const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -597,13 +613,14 @@ test('Parse basic GROUP BY query', () => {
joinCondition: null,
hasAggregateWithoutGroupBy: false,
orderByFields: null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with WHERE clause', () => {
const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -614,13 +631,14 @@ test('Parse GROUP BY query with WHERE clause', () => {
joinCondition: null,
hasAggregateWithoutGroupBy: false,
orderByFields: null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with multiple fields', () => {
const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student_id', 'course', 'COUNT(*)'],
table: 'enrollment',
@@ -631,13 +649,14 @@ test('Parse GROUP BY query with multiple fields', () => {
joinCondition: null,
hasAggregateWithoutGroupBy: false,
orderByFields: null,
- "limit": null
+ "limit": null,
+ isDistinct: false
});
});
test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student.name', 'COUNT(*)'],
table: 'student',
@@ -652,6 +671,7 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
hasAggregateWithoutGroupBy: false,
orderByFields: null,
"limit": null,
+ isDistinct: false,
});
});
diff --git a/tests/step-14/index.test.js b/tests/step-14/index.test.js
index 502411fa7..0bc0e0607 100644
--- a/tests/step-14/index.test.js
+++ b/tests/step-14/index.test.js
@@ -1,6 +1,6 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
const data = await readCSV('./student.csv');
@@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => {
test('Parse SQL Query', () => {
const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -276,7 +276,7 @@ test('Parse SQL Query', () => {
test('Parse SQL Query with WHERE Clause', () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -298,7 +298,7 @@ test('Parse SQL Query with WHERE Clause', () => {
test('Parse SQL Query with Multiple WHERE Clauses', () => {
const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -324,7 +324,7 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
test('Parse SQL Query with INNER JOIN', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -342,7 +342,7 @@ test('Parse SQL Query with INNER JOIN', async () => {
test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -402,7 +402,7 @@ test('Returns null for queries without JOIN', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -420,7 +420,7 @@ test('Parse LEFT Join Query Completely', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -438,7 +438,7 @@ test('Parse LEFT Join Query Completely', () => {
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -456,7 +456,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -474,7 +474,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -492,7 +492,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -511,7 +511,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab
test('Parse COUNT Aggregate Query', () => {
const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['COUNT(*)'],
table: 'student',
@@ -530,7 +530,7 @@ test('Parse COUNT Aggregate Query', () => {
test('Parse SUM Aggregate Query', () => {
const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['SUM(age)'],
table: 'student',
@@ -548,7 +548,7 @@ test('Parse SUM Aggregate Query', () => {
test('Parse AVG Aggregate Query', () => {
const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['AVG(age)'],
table: 'student',
@@ -566,7 +566,7 @@ test('Parse AVG Aggregate Query', () => {
test('Parse MIN Aggregate Query', () => {
const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MIN(age)'],
table: 'student',
@@ -584,7 +584,7 @@ test('Parse MIN Aggregate Query', () => {
test('Parse MAX Aggregate Query', () => {
const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MAX(age)'],
table: 'student',
@@ -602,7 +602,7 @@ test('Parse MAX Aggregate Query', () => {
test('Parse basic GROUP BY query', () => {
const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -620,7 +620,7 @@ test('Parse basic GROUP BY query', () => {
test('Parse GROUP BY query with WHERE clause', () => {
const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -638,7 +638,7 @@ test('Parse GROUP BY query with WHERE clause', () => {
test('Parse GROUP BY query with multiple fields', () => {
const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student_id', 'course', 'COUNT(*)'],
table: 'enrollment',
@@ -656,7 +656,7 @@ test('Parse GROUP BY query with multiple fields', () => {
test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student.name', 'COUNT(*)'],
table: 'student',
diff --git a/tests/step-15/index.test.js b/tests/step-15/index.test.js
index a2aa4daee..dc1fa19ae 100644
--- a/tests/step-15/index.test.js
+++ b/tests/step-15/index.test.js
@@ -1,6 +1,6 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
const data = await readCSV('./student.csv');
@@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => {
test('Parse SQL Query', () => {
const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -276,7 +276,7 @@ test('Parse SQL Query', () => {
test('Parse SQL Query with WHERE Clause', () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -298,7 +298,7 @@ test('Parse SQL Query with WHERE Clause', () => {
test('Parse SQL Query with Multiple WHERE Clauses', () => {
const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -324,7 +324,7 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
test('Parse SQL Query with INNER JOIN', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -342,7 +342,7 @@ test('Parse SQL Query with INNER JOIN', async () => {
test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -402,7 +402,7 @@ test('Returns null for queries without JOIN', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -420,7 +420,7 @@ test('Parse LEFT Join Query Completely', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -438,7 +438,7 @@ test('Parse LEFT Join Query Completely', () => {
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -456,7 +456,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -474,7 +474,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -492,7 +492,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -511,7 +511,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab
test('Parse COUNT Aggregate Query', () => {
const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['COUNT(*)'],
table: 'student',
@@ -530,7 +530,7 @@ test('Parse COUNT Aggregate Query', () => {
test('Parse SUM Aggregate Query', () => {
const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['SUM(age)'],
table: 'student',
@@ -548,7 +548,7 @@ test('Parse SUM Aggregate Query', () => {
test('Parse AVG Aggregate Query', () => {
const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['AVG(age)'],
table: 'student',
@@ -566,7 +566,7 @@ test('Parse AVG Aggregate Query', () => {
test('Parse MIN Aggregate Query', () => {
const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MIN(age)'],
table: 'student',
@@ -584,7 +584,7 @@ test('Parse MIN Aggregate Query', () => {
test('Parse MAX Aggregate Query', () => {
const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MAX(age)'],
table: 'student',
@@ -602,7 +602,7 @@ test('Parse MAX Aggregate Query', () => {
test('Parse basic GROUP BY query', () => {
const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -620,7 +620,7 @@ test('Parse basic GROUP BY query', () => {
test('Parse GROUP BY query with WHERE clause', () => {
const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -638,7 +638,7 @@ test('Parse GROUP BY query with WHERE clause', () => {
test('Parse GROUP BY query with multiple fields', () => {
const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student_id', 'course', 'COUNT(*)'],
table: 'enrollment',
@@ -656,7 +656,7 @@ test('Parse GROUP BY query with multiple fields', () => {
test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student.name', 'COUNT(*)'],
table: 'student',
diff --git a/tests/step-16/index.test.js b/tests/step-16/index.test.js
index a2aa4daee..dc1fa19ae 100644
--- a/tests/step-16/index.test.js
+++ b/tests/step-16/index.test.js
@@ -1,6 +1,6 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const {readCSV} = require('../../src/csvReader');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
+const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
const data = await readCSV('./student.csv');
@@ -258,7 +258,7 @@ test('Average age of students above a certain age', async () => {
test('Parse SQL Query', () => {
const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -276,7 +276,7 @@ test('Parse SQL Query', () => {
test('Parse SQL Query with WHERE Clause', () => {
const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -298,7 +298,7 @@ test('Parse SQL Query with WHERE Clause', () => {
test('Parse SQL Query with Multiple WHERE Clauses', () => {
const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['id', 'name'],
table: 'student',
@@ -324,7 +324,7 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => {
test('Parse SQL Query with INNER JOIN', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -342,7 +342,7 @@ test('Parse SQL Query with INNER JOIN', async () => {
test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -402,7 +402,7 @@ test('Returns null for queries without JOIN', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -420,7 +420,7 @@ test('Parse LEFT Join Query Completely', () => {
test('Parse LEFT Join Query Completely', () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
+ const result = parseSelectQuery(query);
expect(result).toEqual({
fields: ['student.name', 'enrollment.course'],
table: 'student',
@@ -438,7 +438,7 @@ test('Parse LEFT Join Query Completely', () => {
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -456,7 +456,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl
test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -474,7 +474,7 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -492,7 +492,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab
test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
+ const result = await parseSelectQuery(query);
expect(result).toEqual({
"fields": ["student.name", "enrollment.course"],
"joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
@@ -511,7 +511,7 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab
test('Parse COUNT Aggregate Query', () => {
const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['COUNT(*)'],
table: 'student',
@@ -530,7 +530,7 @@ test('Parse COUNT Aggregate Query', () => {
test('Parse SUM Aggregate Query', () => {
const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['SUM(age)'],
table: 'student',
@@ -548,7 +548,7 @@ test('Parse SUM Aggregate Query', () => {
test('Parse AVG Aggregate Query', () => {
const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['AVG(age)'],
table: 'student',
@@ -566,7 +566,7 @@ test('Parse AVG Aggregate Query', () => {
test('Parse MIN Aggregate Query', () => {
const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MIN(age)'],
table: 'student',
@@ -584,7 +584,7 @@ test('Parse MIN Aggregate Query', () => {
test('Parse MAX Aggregate Query', () => {
const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['MAX(age)'],
table: 'student',
@@ -602,7 +602,7 @@ test('Parse MAX Aggregate Query', () => {
test('Parse basic GROUP BY query', () => {
const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -620,7 +620,7 @@ test('Parse basic GROUP BY query', () => {
test('Parse GROUP BY query with WHERE clause', () => {
const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['age', 'COUNT(*)'],
table: 'student',
@@ -638,7 +638,7 @@ test('Parse GROUP BY query with WHERE clause', () => {
test('Parse GROUP BY query with multiple fields', () => {
const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student_id', 'course', 'COUNT(*)'],
table: 'enrollment',
@@ -656,7 +656,7 @@ test('Parse GROUP BY query with multiple fields', () => {
test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
+ const parsed = parseSelectQuery(query);
expect(parsed).toEqual({
fields: ['student.name', 'COUNT(*)'],
table: 'student',
diff --git a/tests/step-17/index.test.js b/tests/step-17/index.test.js
index c99d01fbb..dc1fa19ae 100644
--- a/tests/step-17/index.test.js
+++ b/tests/step-17/index.test.js
@@ -1,5 +1,5 @@
const {readCSV} = require('../../src/csvReader');
-const {executeSELECTQuery } = require('../../src/index');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
diff --git a/tests/step-17/insertExecuter.test.js b/tests/step-17/insertExecuter.test.js
index 8c405f727..9154b0e2e 100644
--- a/tests/step-17/insertExecuter.test.js
+++ b/tests/step-17/insertExecuter.test.js
@@ -1,4 +1,4 @@
-const { executeINSERTQuery } = require('../../src/index');
+const { executeINSERTQuery } = require('../../src/queryExecutor');
const { readCSV, writeCSV } = require('../../src/csvReader');
const fs = require('fs');
@@ -9,6 +9,7 @@ async function createGradesCSV() {
{ student_id: '2', course: 'Chemistry', grade: 'B' },
{ student_id: '3', course: 'Mathematics', grade: 'C' }
];
+ fs.writeFileSync('grades.csv', '');
await writeCSV('grades.csv', initialData);
}
diff --git a/tests/step-18/deleteExecutor.test.js b/tests/step-18/deleteExecutor.test.js
index 11ae617b7..636403858 100644
--- a/tests/step-18/deleteExecutor.test.js
+++ b/tests/step-18/deleteExecutor.test.js
@@ -1,4 +1,4 @@
-const { executeDELETEQuery } = require('../../src/index');
+const { executeDELETEQuery } = require('../../src/queryExecutor');
const { readCSV, writeCSV } = require('../../src/csvReader');
const fs = require('fs');
diff --git a/tests/step-18/index.test.js b/tests/step-18/index.test.js
index c99d01fbb..dc1fa19ae 100644
--- a/tests/step-18/index.test.js
+++ b/tests/step-18/index.test.js
@@ -1,5 +1,5 @@
const {readCSV} = require('../../src/csvReader');
-const {executeSELECTQuery } = require('../../src/index');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
diff --git a/tests/step-18/insertExecuter.test.js b/tests/step-18/insertExecuter.test.js
index 8c405f727..581d17f73 100644
--- a/tests/step-18/insertExecuter.test.js
+++ b/tests/step-18/insertExecuter.test.js
@@ -1,4 +1,4 @@
-const { executeINSERTQuery } = require('../../src/index');
+const { executeINSERTQuery } = require('../../src/queryExecutor');
const { readCSV, writeCSV } = require('../../src/csvReader');
const fs = require('fs');
diff --git a/tests/step-19/.cph/.insertExecuter.test.js_344b632c9c4863f3843be516d9be4761.prob b/tests/step-19/.cph/.insertExecuter.test.js_344b632c9c4863f3843be516d9be4761.prob
new file mode 100644
index 000000000..a677ab136
--- /dev/null
+++ b/tests/step-19/.cph/.insertExecuter.test.js_344b632c9c4863f3843be516d9be4761.prob
@@ -0,0 +1 @@
+{"name":"Local: insertExecuter","url":"/home/pratyush/github-classroom/status-20X/stylusdb-sql-assignment-bruno-noir/tests/step-19/insertExecuter.test.js","tests":[{"id":1714807548051,"input":"","output":""}],"interactive":false,"memoryLimit":1024,"timeLimit":3000,"srcPath":"/home/pratyush/github-classroom/status-20X/stylusdb-sql-assignment-bruno-noir/tests/step-19/insertExecuter.test.js","group":"local","local":true}
\ No newline at end of file
diff --git a/tests/step-19/deleteExecutor.test.js b/tests/step-19/deleteExecutor.test.js
index 11ae617b7..636403858 100644
--- a/tests/step-19/deleteExecutor.test.js
+++ b/tests/step-19/deleteExecutor.test.js
@@ -1,4 +1,4 @@
-const { executeDELETEQuery } = require('../../src/index');
+const { executeDELETEQuery } = require('../../src/queryExecutor');
const { readCSV, writeCSV } = require('../../src/csvReader');
const fs = require('fs');
diff --git a/tests/step-19/index.test.js b/tests/step-19/index.test.js
index c99d01fbb..dc1fa19ae 100644
--- a/tests/step-19/index.test.js
+++ b/tests/step-19/index.test.js
@@ -1,5 +1,5 @@
const {readCSV} = require('../../src/csvReader');
-const {executeSELECTQuery } = require('../../src/index');
+const {executeSELECTQuery } = require('../../src/queryExecutor');
const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
test('Read CSV File', async () => {
diff --git a/tests/step-19/insertExecuter.test.js b/tests/step-19/insertExecuter.test.js
index 8c405f727..95453731b 100644
--- a/tests/step-19/insertExecuter.test.js
+++ b/tests/step-19/insertExecuter.test.js
@@ -1,33 +1,72 @@
-const { executeINSERTQuery } = require('../../src/index');
+const { executeINSERTQuery } = require('../../src/queryExecutor');
const { readCSV, writeCSV } = require('../../src/csvReader');
const fs = require('fs');
-// Helper function to create grades.csv with initial data
+
async function createGradesCSV() {
- const initialData = [
- { student_id: '1', course: 'Mathematics', grade: 'A' },
- { student_id: '2', course: 'Chemistry', grade: 'B' },
- { student_id: '3', course: 'Mathematics', grade: 'C' }
- ];
- await writeCSV('grades.csv', initialData);
+
+ const initialData = [
+
+ { student_id: "1", course: "Mathematics", grade: "A" },
+
+ { student_id: "2", course: "Chemistry", grade: "B" },
+
+ { student_id: "3", course: "Mathematics", grade: "C" },
+
+ ];
+
+ await writeCSV("grades.csv", initialData);
+
}
+
+
+
// Test to INSERT a new grade and verify
-test('Execute INSERT INTO Query for grades.csv', async () => {
- // Create grades.csv with initial data
- await createGradesCSV();
-
- // Execute INSERT statement
- const insertQuery = "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')";
- await executeINSERTQuery(insertQuery);
-
- // Verify the new entry
- const updatedData = await readCSV('grades.csv');
- const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics');
- console.log(updatedData)
- expect(newEntry).toBeDefined();
- expect(newEntry.grade).toEqual('A');
-
- // Cleanup: Delete grades.csv
- fs.unlinkSync('grades.csv');
+
+test("Execute INSERT INTO Query for grades.csv", async () => {
+
+ // Create grades.csv with initial data
+
+ await createGradesCSV();
+
+
+
+
+ // Execute INSERT statement
+
+ const insertQuery =
+
+ "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')";
+
+ await executeINSERTQuery(insertQuery);
+
+
+
+
+ // Verify the new entry
+
+ const updatedData = await readCSV("grades.csv");
+
+ const newEntry = updatedData.find(
+
+ (row) => row.student_id === "4" && row.course === "Physics"
+
+ );
+
+
+
+
+
+ expect(newEntry).toBeDefined();
+
+ expect(newEntry.grade).toEqual("A");
+
+
+
+
+ // Cleanup: Delete grades.csv
+
+ fs.unlinkSync("grades.csv");
+
});
\ No newline at end of file
From 1876454769fd38d379a8572900341b1478d8a813 Mon Sep 17 00:00:00 2001
From: Divy Vinayak Diwedi
Date: Sun, 5 May 2024 20:34:26 +0530
Subject: [PATCH 15/15] assignment finished with all test cases passed
---
src/csvReader.js | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/src/csvReader.js b/src/csvReader.js
index 1296d8a25..f07cf3db4 100644
--- a/src/csvReader.js
+++ b/src/csvReader.js
@@ -2,21 +2,6 @@ const fs = require('fs');
const csv = require('csv-parser');
const { parse } = require('json2csv');
-// function readCSV(filePath) {
-// const results = [];
-
-// return new Promise((resolve, reject) => {
-// fs.createReadStream(filePath)
-// .pipe(csv())
-// .on('data', (data) => results.push(data))
-// .on('end', () => {
-// resolve(results);
-// })
-// .on('error', (error) => {
-// reject(error);
-// });
-// });
-// }
function readCSV(filePath) {
const results = [];
return new Promise((resolve, reject) => {