From 1b46ba95fc725a0dd29f5226ffc921350ef99c0f Mon Sep 17 00:00:00 2001 From: ariflogs Date: Sat, 14 Oct 2023 04:43:37 +0600 Subject: [PATCH 1/4] added install doc for yarn & pnpm --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 1eccbe2..72f9b6a 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,14 @@ The project is under active development and is not yet ready to use in productio ```bash npm insall sql-to-nosql + +# or + +yarn add sql-to-nosql + +# or + +pnpm add sql-to-nosql ``` ## Usage From 30fa3f56f02b59a1237f74cab808b0e981506f41 Mon Sep 17 00:00:00 2001 From: ariflogs Date: Sat, 14 Oct 2023 17:52:31 +0600 Subject: [PATCH 2/4] =?UTF-8?q?prettier=20checking=20is=20back!=20?= =?UTF-8?q?=F0=9F=91=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e8d24e0..5e902c7 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "start": "tsc && node dist/index.mjs", "check": "npx prettier . --check", "pretty": "npx prettier . --write", - "build": "tsc", + "build": "tsc && npm run check", "test": "echo \"Error: no test specified\" && exit 1" }, "author": { From 2ec105c504ff37f9a92507fe88d68258a04aab37 Mon Sep 17 00:00:00 2001 From: ariflogs Date: Sun, 15 Oct 2023 02:47:52 +0600 Subject: [PATCH 3/4] =?UTF-8?q?added=20contributors=20guidline=20=E2=9C=8C?= =?UTF-8?q?=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .npmignore | 3 ++- CONTRIBUTING.md | 26 ++++++++++++++++++++++++++ README.md | 3 +++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 CONTRIBUTING.md diff --git a/.npmignore b/.npmignore index 4d87dbb..87b215f 100644 --- a/.npmignore +++ b/.npmignore @@ -2,4 +2,5 @@ src test .github .gitignore -TODO.md \ No newline at end of file +TODO.md +CONTRIBUTING.md \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..0af21fb --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,26 @@ +## Before You Contribute + +### Raise an Issue First +Before you invest a significant amount of time on a change, please create a issue describing your proposal. This will help us to make sure that the change is in line with the project's goals, roadmap and avoid duplicate work. + +### Avoid Dependencies +We want to keep the project as lightweight as possible. So, please avoid adding any new dependencies unless it's absolutely necessary. + +--- + +## Contributing + +- Fork the repository on GitHub to your personal account. +- Clone your forked repository to your local development environment. +- Create a new branch for your feature or bug fix: ```git checkout -b your-branch-name``` +- Install the project dependencies: ```pnpm i``` +- Run the project in development mode: ```pnpm dev``` +- Make changes to your local repository. +- Commit your changes and push them to your forked repository. +- Open a pull request from your forked repository to the **dev branch** of this repository. + +## Code Licensing + +Your contributions are subject to the project's open-source(MIT) license. By submitting a PR, you agree to release your code under this license. + +## Thanks for your contribution! \ No newline at end of file diff --git a/README.md b/README.md index 72f9b6a..5cb9dac 100644 --- a/README.md +++ b/README.md @@ -91,3 +91,6 @@ console.log(resp); - [ ] IS NULL - [ ] IS NOT NULL - [ ] Typescript Support + +## Contributing +Read the [contributing guide](./CONTRIBUTING.md) to learn how you can contribute to this project. From b9b469d3010c3c377b7c6971ce36cd76f98ac2e8 Mon Sep 17 00:00:00 2001 From: ariflogs Date: Mon, 16 Oct 2023 00:24:53 +0600 Subject: [PATCH 4/4] =?UTF-8?q?added=20support=20for=20searching=20specifi?= =?UTF-8?q?c=20columns/fields=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTING.md | 10 +++++---- README.md | 1 + package.json | 2 +- src/config/mapping.mts | 6 +++--- src/index.mts | 47 ++++++++++++++++++++++++++++-------------- src/types/nosql.mts | 21 +++++++++++++++++++ src/types/sql.mts | 8 ++++--- src/utils/parser.mts | 3 ++- 8 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 src/types/nosql.mts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0af21fb..34430c5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,11 @@ ## Before You Contribute ### Raise an Issue First + Before you invest a significant amount of time on a change, please create a issue describing your proposal. This will help us to make sure that the change is in line with the project's goals, roadmap and avoid duplicate work. ### Avoid Dependencies + We want to keep the project as lightweight as possible. So, please avoid adding any new dependencies unless it's absolutely necessary. --- @@ -12,9 +14,9 @@ We want to keep the project as lightweight as possible. So, please avoid adding - Fork the repository on GitHub to your personal account. - Clone your forked repository to your local development environment. -- Create a new branch for your feature or bug fix: ```git checkout -b your-branch-name``` -- Install the project dependencies: ```pnpm i``` -- Run the project in development mode: ```pnpm dev``` +- Create a new branch for your feature or bug fix: `git checkout -b your-branch-name` +- Install the project dependencies: `pnpm i` +- Run the project in development mode: `pnpm dev` - Make changes to your local repository. - Commit your changes and push them to your forked repository. - Open a pull request from your forked repository to the **dev branch** of this repository. @@ -23,4 +25,4 @@ We want to keep the project as lightweight as possible. So, please avoid adding Your contributions are subject to the project's open-source(MIT) license. By submitting a PR, you agree to release your code under this license. -## Thanks for your contribution! \ No newline at end of file +## Thanks for your contribution! diff --git a/README.md b/README.md index 5cb9dac..09833aa 100644 --- a/README.md +++ b/README.md @@ -93,4 +93,5 @@ console.log(resp); - [ ] Typescript Support ## Contributing + Read the [contributing guide](./CONTRIBUTING.md) to learn how you can contribute to this project. diff --git a/package.json b/package.json index 5e902c7..6dcfc77 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql-to-nosql", - "version": "0.1.01", + "version": "0.1.02", "description": "Run SQL quries on your Mongodb database.", "repository": { "type": "git", diff --git a/src/config/mapping.mts b/src/config/mapping.mts index d8e5e44..dfbe1da 100644 --- a/src/config/mapping.mts +++ b/src/config/mapping.mts @@ -1,13 +1,13 @@ export const sqlToMongoDBcommandsMapping = { - select: "find", // s! + select: "find", insert: "insertMany", update: "updateMany", delete: "deleteMany", } as const; export const sqlToMongoDBoperatorsMapping = { - "=": "$eq", // s! - "!=": "$ne", // s! + "=": "$eq", + "!=": "$ne", ">": "$gt", "<": "$lt", ">=": "$gte", diff --git a/src/index.mts b/src/index.mts index 935b1c4..9457c79 100644 --- a/src/index.mts +++ b/src/index.mts @@ -4,6 +4,7 @@ import { mappings } from "./config/mapping.mjs"; import { parseQuery } from "./utils/parser.mjs"; import { connect } from "./utils/database.mjs"; import { SqlToNoSqlType } from "./types/index.mjs"; +import { MongoFindOperationType } from "types/nosql.mjs"; export class SqlToNoSql { client: MongoClient | undefined; @@ -22,29 +23,43 @@ export class SqlToNoSql { const q = parseQuery(query); - const filters: { - [key: string]: { - [operator: string]: string | number; - }; - } = {}; + if (q.command !== "select") { + throw new Error("Only select queries are supported"); + } + + const mongoQuery: MongoFindOperationType = { + collection: q.table, + [q.command]: mappings["mongodb"]["commands"][q.command], + query: {}, + fields: { + // coz mongodb by default returns _id + _id: 0, + }, + }; + + // Convert parsed columns to document fields + q.columns?.forEach((column) => { + if (column === "*") { + return; + } + if (column === "_id") { + mongoQuery.fields["_id"] = 1; + return; + } + mongoQuery.fields[column] = 1; + }); // Convert parsed filters to MongoDB query q.filters?.forEach((filter) => { const { column, operator, value } = filter; - if (!filters[column]) { - filters[column] = { + if (!mongoQuery.query[column]) { + mongoQuery.query[column] = { [mappings["mongodb"]["operators"][operator]]: value, }; } }); - const mongoQuery = { - collection: q.table, - [q.command]: mappings["mongodb"]["commands"][q.command], - query: filters, - }; - try { if (!this.client) { this.client = await connect(this.config.connection); @@ -54,9 +69,9 @@ export class SqlToNoSql { const db = this.client.db(); const collection = db.collection(mongoQuery.collection); - const data = await collection[mongoQuery[q.command]]( - mongoQuery.query, - ).toArray(); + const data = await collection[mongoQuery[q.command]](mongoQuery.query, { + projection: mongoQuery.fields, + }).toArray(); return data; } catch (err) { diff --git a/src/types/nosql.mts b/src/types/nosql.mts new file mode 100644 index 0000000..67491a0 --- /dev/null +++ b/src/types/nosql.mts @@ -0,0 +1,21 @@ +import { mappings } from "config/mapping.mjs"; +import { SqlCommandOptions } from "./sql.mjs"; + +export type MongoCommandOptions = "find" | "insertMany"; + +export interface MongoQueryType { + [key: string]: { + [operator: string]: string | number; + }; +} + +export interface MongoFieldSelectionType { + [key: string]: 1 | 0; +} + +export interface MongoFindOperationType { + select: (typeof mappings)["mongodb"]["commands"]["select"]; // sql -> mongodb + collection: string; + query: MongoQueryType; + fields: MongoFieldSelectionType; +} diff --git a/src/types/sql.mts b/src/types/sql.mts index e06bc65..954e55a 100644 --- a/src/types/sql.mts +++ b/src/types/sql.mts @@ -1,12 +1,14 @@ -interface filterType { +export type SqlCommandOptions = "select" | "insert"; + +interface FilterType { column: string; operator: "="; value: string | number; } export interface ParsedSqlType { - command: "select"; + command: SqlCommandOptions; table: string; columns: string[]; - filters: filterType[] | null; + filters: FilterType[] | null; } diff --git a/src/utils/parser.mts b/src/utils/parser.mts index 47cd9b8..415c08d 100644 --- a/src/utils/parser.mts +++ b/src/utils/parser.mts @@ -10,7 +10,8 @@ export const parseQuery = (query: string): ParsedSqlType => { filters: null, }; - const [command, ...rest] = query.split(" "); + // for splliting by comma and space + const [command, ...rest] = query.split(/, |,| /); const lowerCaseCommand = command.toLowerCase(); if (lowerCaseCommand !== "select") {