{"id":14972190,"url":"https://github.com/walidadebayo/mappifysql","last_synced_at":"2025-10-26T18:31:41.658Z","repository":{"id":235895582,"uuid":"791472687","full_name":"Walidadebayo/MappifySQL","owner":"Walidadebayo","description":"MappifySQL is a lightweight, easy-to-use Object-Relational Mapping (ORM) library for MySQL databases, designed for use with Node.js. It provides an intuitive, promise-based API for interacting with your MySQL database using JavaScript or TypeScript.","archived":false,"fork":false,"pushed_at":"2024-11-06T00:00:08.000Z","size":183,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-31T22:22:26.822Z","etag":null,"topics":["javascript","mysql","mysql-connector","mysql-database","mysql-server","mysql2","node-js","nodejs","nodemon","oop","orm"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/mappifysql","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Walidadebayo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-24T19:27:42.000Z","updated_at":"2024-11-06T00:00:11.000Z","dependencies_parsed_at":"2024-09-08T18:32:42.115Z","dependency_job_id":"3bb994f6-15b7-4bf1-b14a-5b97a43a87dc","html_url":"https://github.com/Walidadebayo/MappifySQL","commit_stats":{"total_commits":24,"total_committers":1,"mean_commits":24.0,"dds":0.0,"last_synced_commit":"8942becdcbe0fd656e47993024dc005451e6fe4b"},"previous_names":["walidadebayo/mappifysql"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Walidadebayo%2FMappifySQL","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Walidadebayo%2FMappifySQL/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Walidadebayo%2FMappifySQL/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Walidadebayo%2FMappifySQL/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Walidadebayo","download_url":"https://codeload.github.com/Walidadebayo/MappifySQL/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238386101,"owners_count":19463298,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","mysql","mysql-connector","mysql-database","mysql-server","mysql2","node-js","nodejs","nodemon","oop","orm"],"created_at":"2024-09-24T13:46:31.145Z","updated_at":"2025-10-26T18:31:41.258Z","avatar_url":"https://github.com/Walidadebayo.png","language":"JavaScript","funding_links":["https://www.buymeacoffee.com/walidadebayo","https://img.buymeacoffee.com/button-api/?text=Buy"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"https://i.ibb.co/tmH8Kk4/mappifysql.jpg\" alt=\"mappifysql\" style=\"height: 300px; width: 300px; border-radius: 100%; object-fit: cover;\"\u003e\n\u003c/div\u003e\n\n---\n\n\u003ca href=\"https://www.npmjs.com/package/mappifysql\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/mappifysql.svg\" alt=\"Version\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/mappifysql\"\u003e\u003cimg src=\"https://img.shields.io/npm/dt/mappifysql.svg\" alt=\"Downloads\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/mappifysql\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/mappifysql.svg\" alt=\"License\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/mappifysql\"\u003e\u003cimg src=\"https://img.shields.io/bundlephobia/min/mappifysql.svg\" alt=\"Size\"\u003e\u003c/a\u003e\n\n# MappifySQL: A MySQL ORM for Node.js and TypeScript\n\nMappifySQL is a lightweight, easy-to-use Object-Relational Mapping (ORM) library for MySQL databases, designed for use with Node.js. It provides an intuitive, promise-based API for interacting with your MySQL database using JavaScript or TypeScript.\n\n## Table of Contents\n- [Features](#features)\n- [Why MappifySQL?](#why-mappifysql)\n- [Installation](#installation)\n- [Getting Started](#getting-started)\n  - [Connecting to a Database](#connecting-to-a-database)\n  - [Class, Function, and Object available in MappifySQL](#class-function-and-object-available-in-mappifysql)\n  - [Using the Query Method](#using-the-query-method)\n  - [Using the Connection Object](#using-the-connection-object)\n  - [Using the Model Class](#using-the-model-class)\n  - [Performing CRUD Operations](#performing-crud-operations)\n  - [Transactions](#transactions)\n  - [Relationships](#relationships)\n- [Issues](#issues)\n- [License](#license)\n- [References](#references)\n\n## Features\n\n- **Object-Relational Mapping**: Map your database tables to JavaScript or TypeScript objects for easier and more intuitive data manipulation.\n- **Auto Connection**: Automatically connect to your database using environment variables.\n- **Connection Pooling**: Use connection pooling to improve performance and scalability in your application.\n- **Model Class**: Define a model class for each table in your database to encapsulate database operations.\n- **CRUD Operations**: Easily perform Create, Read, Update, and Delete operations on your database.\n- **Transactions**: Safely execute multiple database operations at once with transaction support.\n- **Relationships**: Define relationships between your tables to easily fetch related data.\n- **Environment Variables**: Use environment variables to store database connection details securely.\n- **TypeScript Support**: Use MappifySQL with TypeScript for type-safe database interactions.\n- **SQL Injection Protection**: Protect your application from SQL injection attacks with parameterized queries.\n- **Custom Queries**: Execute custom SQL queries using the query method.\n- **Custom Functions**: Create custom functions in your model classes to encapsulate complex queries or operations.\n- **Pagination**: Implement pagination for large datasets with the limit and offset options.\n\n\n## Why MappifySQL?\n\nMappifySQL aims to simplify working with MySQL databases in Node.js applications. By providing an object-oriented interface to your database, it allows you to write more readable and maintainable code. Whether you're building a small application or a large, complex system, MappifySQL has the features you need to get the job done.\n\n## Installation\n\nTo install MappifySQL, use npm:\n\n```bash\nnpm install mappifysql\n```\n\n## Getting Started\n\n\n### import and use the library in your JavaScript or TypeScript file:\n\n```javascript\nconst mappifysql = require('mappifysql');\n\nconst MappifyModel = mappifysql.MappifyModel;\n```\n\n```typescript\nimport mappifysql from 'mappifysql';\n\nconst MappifyModel = mappifysql.MappifyModel;\n```\n\n#### import the classes directly in your JavaScript or TypeScript file:\n\n```javascript\nconst { MappifyModel } = require('mappifysql');\n```\n\n```typescript\nimport { MappifyModel } from 'mappifysql';\n```\n\nHere's a quick example to create a connection to a MySQL database using MappifySQL:\n\n### Connecting to a Database\n\nTo connect to a MySQL database using MappifySQL, you need to create a .env file in the root directory of your project and add the following environment variables:\n\n```bash\nDB_HOST=localhost\nDB_USER=root\nDB_PASSWORD=password\nDB_NAME=mydatabase\nDB_PORT=3306 ## (optional) default is 3306\n\nDB_USE_POOL=true ## (optional) default is false ## For pool connection\n\n# For connection pooling\nDB_WAIT_FOR_CONNECTIONS=true ## (optional) default is true\nDB_CONNECTION_LIMIT=10 ## (optional) default is 10\nDB_MAX_IDLE=10 ## (optional) default is set to the connection limit\nDB_IDLE_TIMEOUT=60000 ## (optional) default is 60000\nDB_QUEUE_LIMIT=0 ## (optional) default is 0\nDB_ENABLE_KEEP_ALIVE=true ## (optional) default is true\nDB_KEEP_ALIVE_INITIAL_DELAY=0 ## (optional) default is 0\n\n```\n\n### Class, Function, and Object available in MappifySQL\n\n| Class/Function/Object | Description |\n| --- | --- |\n| `MappifyModel` | Base class for defining models that represent database tables. |\n| `query` | Function for executing SQL queries. |\n| `connection` | Object representing the current MySQL connection. |\n| `beginTransaction` | Function to begin a new transaction. |\n| `commit` | Function to commit the current transaction. |\n| `rollback` | Function to roll back the current transaction. |\n\n\n### Using the Query Method\n\nThe query method allows you to execute SQL queries and returns a promise that resolves with the result of the query. You can use this method to perform CRUD operations, fetch data, and more.\n\n\nHere's an example of how to use the query method to fetch all records from a table:\n\n```javascript\nconst { query } = require('mappifysql');\n// import { query } from 'mappifysql';\n\n\nlet fetchAll = async () =\u003e {\n    try {\n        let results = await query('SELECT * FROM users');\n        console.log('Fetched records:', results);\n    } catch (err) {\n        console.error(err);\n    }\n};\n\nlet addData = async () =\u003e {\n    try {\n        let result = await query('INSERT INTO users (first_name, email) VALUES (?, ?)', ['John Doe', 'example@gmail.com']);\n        console.log('New record - inserted id:', result.insertId);\n    } catch (err) {\n        console.error(err);\n    }\n};\n```\n\u003cspan style=\"color:red;\"\u003e\u003cb\u003eNote\u003c/b\u003e\u003c/span\u003e: The query method returns a promise that resolves with the result of the query. You can use async/await or then and catch to handle the asynchronous nature of the database operations.\n\n### Using the Connection Object\n\nThe connection object provides methods for interacting with the database. You can use the query method to execute SQL queries and the other methods to query the database, manage transactions, ping the server, and more.\n\n```javascript\nconst { connection } = require('mappifysql');\n// import { connection } from 'mappifysql';\n\n(async () =\u003e {\n    let conn = await connection;\n    console.log('Connected to database:', conn.threadId);\n\n    // Perform database operations here\n    conn.query('SELECT * FROM users', (err, results) =\u003e {\n        if (err) {\n            console.error(err);\n        } else {\n            console.log('Fetched records:', results);\n        }\n    });\n\n    //ping the server\n    conn.ping((err) =\u003e {\n        if (err) {\n            console.error(err);\n        } else {\n            console.log('Server pinged successfully');\n        }\n    });\n\n    // End the connection\n    conn.end(); // or conn.release() to release the connection back to the pool\n\n\n    conn.pause();\n\n    setTimeout(() =\u003e {\n        conn.resume();\n    }, 5000);\n\n})();\n```\n    \n\nHere's a list of the methods available in the connection object:\nyou can also use other methods available in the connection object that are not listed here but are available in the mysql library.\n\n| Method | Description | Parameters |\n| --- | --- | --- |\n| `authorized` | The authorized status of the connection. | None |\n| `beginTransaction` | Begins a transaction. | `callback?: (err: any) =\u003e void` |\n| `changeUser` | Changes the user for the current connection. | `options: any`, `callback?: (err: any) =\u003e void` |\n| `commit` | Commits the current transaction. | `callback?: (err: any) =\u003e void` |\n| `destroy` | Destroys the connection. | None |\n| `emit` | Synchronously calls each of the listeners registered for the event named eventName. | `event: string | symbol`, `...args: any[]` |\n| `end` | Ends the connection. | `callback?: (err: any) =\u003e void` |\n| `escape` | Escapes a value for SQL. | `value: any` |\n| `escapeId` | Escapes an identifier for SQL. | `value: any` |\n| `execute` | Executes a SQL query and returns a promise. | `sql: string`, `callback?: any` |\n| `format` | Formats a SQL query string. | `sql: string`, `values?: any` |\n| `once` | Adds a one-time listener function for the event named eventName. | `event: string | symbol`, `listener: (...args: any[]) =\u003e void` |\n| `on` | Adds the listener function to the end of the listeners array for the event named eventName. | `event: string | symbol`, `listener: (...args: any[]) =\u003e void` |\n| `pause` | Pauses the connection. | None |\n| `ping` | Pings the server. | `callback?: (err: any) =\u003e void` |\n| `prepare` | Prepares a SQL statement. | `sql: string`, `callback?: (err: any, statement: PrepareStatementInfo) =\u003e void` |\n| `promise` | Returns a promise that resolves to the connection. | `promiseImpl?: PromiseConstructor` |\n| `query` | Sends a SQL query to the database. | `sql: string`, `values?: any`, `callback?: (error: any, results: any, fields: any) =\u003e void` |\n| `release` | Releases the connection back to the pool. | None |\n| `releaseConnection` | Releases a connection back to the pool. | `connection: PoolConnection` |\n| `resume` | Resumes the connection. | None |\n| `rollback` | Rolls back the current transaction. | `callback?: (err: any) =\u003e void` |\n| `sequenceId` | The sequence ID of the connection. | None |\n| `serverHandshake` | The server handshake. | `args: any` |\n| `threadId` | The thread ID of the connection. | None |\n| `unprepare` | Unprepares a previously prepared statement. | `sql: string` |\n\n\n\n### Using the Model Class\n\nMappifySQL provides a Model class that allows you to define a JavaScript class that represents a table in your database. This class provides methods for performing CRUD operations on the table. \n\nHere's an example of how to define a model class:\ncreate a new file (e.g., Users.js) and add the following code:\n\n```javascript\nconst { MappifyModel } = require('mappifysql');\n\nclass User extends MappifyModel {\n\n}\n\nmodule.exports = User;\n\n```\n\n** Using TypeScript **\n\n```typescript\nimport { MappifyModel } from 'mappifysql';\n\ninterface UserAttributes {\n    id?: number;\n    first_name: string;\n    last_name: string;\n    email: string;\n    password: string;\n    \n    //add more attributes here...\n}\n\nclass User extends MappifyModel {\n\n    id?: number;\n    first_name: string;\n    last_name: string;\n    email: string;\n    password: string;\n\n\n    constructor(data: UserAttributes) {\n        super();\n        this.id = data.id;\n        this.first_name = data.first_name;\n        this.last_name = data.last_name;\n        this.email = data.email;\n        this.password = data.password;\n\n        // add more properties here...\n    }\n   \n}\n\nexport default User;\n\n```\n\n**Note**: By default, the Model class uses the table name derived from the class name and assumes that the table name in the database is the plural form of the class name. If your table name is different, you can override the tableName property in your model class.\n\n```javascript\nconst { MappifyModel } = require('mappifysql');\n\nclass User extends MappifyModel {\n    static get tableName() {\n        return 'my_user_table_name';\n    }\n}\n\nmodule.exports = User;\n\n```\n\n** Using TypeScript **\n\n```typescript\nimport { MappifyModel } from 'mappifysql';\n\nclass User extends MappifyModel {\n    static get tableName() {\n        return 'my_user_table_name';\n    }\n}\n\nexport default User;\n\n```\n\n\n### Performing CRUD Operations\n\nOnce you have defined a model, you can use it to perform CRUD operations on the corresponding table.\n\n```javascript\nconst User = require('path/to/user.js')\n\n// Example: Fetch all records from the table\n\nlet fetchAll = async () =\u003e {\n    User.findAll().then((results) =\u003e {\n        console.log('Fetched records:', results);\n    }).catch((err) =\u003e {\n        console.error(err);\n    });\n};\n\n// Example: Create a new record\n\nlet addData = async () =\u003e {\n    let newUser = new User({ name: 'John Doe', email: 'john.doe@example.com' });\n    newUser.save().then(() =\u003e {\n        console.log('New record inserted successfully');\n    }).catch((err) =\u003e {\n        console.error(err);\n    });\n};\n\n// Example: Update a record\n\nlet updateData = async () =\u003e {\n    User.findById(1).then((record) =\u003e {\n        record.setProperties({ name: 'Jane Doe', email: 'jane.doe@example.com' });\n        record.update().then(() =\u003e {\n            console.log('Record updated successfully');\n        }).catch((err) =\u003e {\n            console.error(err);\n        });\n    }).catch((err) =\u003e {\n        console.error(err);\n    });\n};\n\nlet updateData = async () =\u003e {\n    let user = await User.findOneAndUpdate({ where: { email: 'user@example.com' } }, { name: 'Jane Doe', email: 'user2@example.com' });\n    if (user) {\n        console.log('Record updated successfully');\n    } else {\n        console.log('Record not found');\n    }\n};\n\n// Example: Delete a record\n\nlet deleteData = async () =\u003e {\n    User.findByIdAndDelete(1).then(() =\u003e {\n        console.log('Record deleted successfully');\n    }).catch((err) =\u003e {\n        console.error(err);\n    });\n};\n```\n\n** Import in TypeScript **\n\n```typescript\nimport User from 'path/to/user.ts'\n```\n\n\n# Model Class\n\nThis file contains a base model class with methods for interacting with a database. Each method corresponds to a common database operation.\n\n## Methods\n\n### MappifySQL save Method\n\nThis method inserts a new record into the database. It uses the properties of the instance to determine the column names and values.\nIt returns a promise that resolves with the id of the newly inserted record.\n\nExample:\n```javascript\n// you can use also Async/Await\nlet user = new User({ name: 'John Doe', email: 'joh.doe@example.com' });\nuser.save().then((id) =\u003e {\n    console.log('New record inserted successfully', id);\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n// save returns the id of the newly inserted record\n```\n\n### MappifySQL Update Method\n\nThis method updates the record associated with the instance in the database. It uses the properties of the instance to determine the column names and values.\nIt returns a promise that resolves with a boolean value indicating whether the record was updated successfully.\n\nExample:\n```javascript\n// you can use also Async/Await\nUser.findById(1).then((record) =\u003e {\n    record.setProperties({ name: 'Jane Doe', email: 'janedoe@example.com' });\n    record.update().then(() =\u003e {\n        console.log('Record updated successfully');\n    }).catch((err) =\u003e {\n        console.error(err);\n    });\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n// update returns the true if the record was updated successfully\n```\n\n\n### MappifySQL delete Method\n\nThis method deletes the record associated with the instance from the database.\n\nExample:\n```javascript\n// you can use also Async/Await\nUser.findById(1).then((record) =\u003e {\n    record.delete().then(() =\u003e {\n        console.log('Record deleted successfully');\n    }).catch((err) =\u003e {\n        console.error(err);\n    });\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n// delete returns the true if the record was deleted successfully\n```\n\n### MappifySQL fetch Method\n\nThis method fetches all the records associated with the instance from the database.\n\nExample:\n```javascript\n// you can use also Async/Await\nUser.fetch().then((records) =\u003e {\n    console.log('Fetched records:', records);\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n// fetch returns an array of records\n```\n\n### MappifySQL findOne Method\n\nThis method finds one record in the database that matches the specified conditions. The parameter is an object that can contain the following properties:\n\n- `where`: An object specifying the conditions for the query. - \u003cspan style=\"color: red;\"\u003e **required** \u003c/span\u003e\n- `exclude`: An array of column names to exclude from the result.\n- `attributes`: An array of column names to include in the result.\n\n```javascript\n// Fetch a user with all columns from the database using the email\nconst user = await User.findOne({ where: { email: 'user@example.com' } });\n\n// Fetch a product with the id 1 and exclude the 'description' column from the result\nconst product = await Product.findOne({ where: { id: 1 }, exclude: ['description'] });\n\n// Fetch a user with the role 'admin' and only include the 'id', 'name', and 'email' columns in the result\nconst admin = await User.findOne({ where: { role: 'admin' }, attributes: ['id', 'name', 'email'] });\n\n// Fetch a record using operations\n\n// Equal to\nconst user = await User.findOne({ where: { age: { eq: 18 } } });\n// run this query: SELECT * FROM users WHERE age = 18;\n\n// Greater than\nconst user = await User.findOne({ where: { age: { gt: 17 } } });\n// run this query: SELECT * FROM users WHERE age \u003e 17;\n\n// Less than\nconst user = await User.findOne({ where: { age: { lt: 10 } } });\n// run this query: SELECT * FROM users WHERE age \u003c 10;\n\n// Greater than or equal to\nconst user = await User.findOne({ where: { age: { gte: 18 } } });\n// run this query: SELECT * FROM users WHERE age \u003e= 18;\n\n// Less than or equal to\nconst user = await User.findOne({ where: { age: { lte: 10 } } });\n// run this query: SELECT * FROM users WHERE age \u003c= 10;\n\n// Not equal to\nconst user = await User.findOne({ where: { age: { ne: 18 } } });\n// run this query: SELECT * FROM users WHERE age \u003c\u003e 18;\n\n//greater than and less than\nconst user = await User.findOne({ where: { age: { gt: 10, lt: 20 } } });\n// run this query: SELECT * FROM users WHERE age \u003e 10 AND age \u003c 20;\n\n//like\nconst product = await Product.findOne({ where: { name: { like: '%apple%' } } });\n// run this query: SELECT * FROM products WHERE name LIKE '%apple%';\n\n//not like\nconst product = await Product.findOne({ where: { name: { notLike: '%apple%' } } });\n// run this query: SELECT * FROM products WHERE name NOT LIKE '%apple%';\n\n//in\nconst product = await Product.findOne({ where: { category: { in: ['electronics', 'clothing'] } } });\n// run this query: SELECT * FROM products WHERE category IN ('electronics', 'clothing');\n\n//not in\nconst product = await Product.findOne({ where: { category: { notIn: ['electronics', 'clothing'] } } });\n// run this query: SELECT * FROM products WHERE category NOT IN ('electronics', 'clothing');\n\n//between\nconst product = await Product.findOne({ where: { price: { between: [10, 20] } } });\n// run this query: SELECT * FROM products WHERE price BETWEEN 10 AND 20;\n\n//not between\nconst product = await Product.findOne({ where: { price: { notBetween: [10, 20] } } });\n// run this query: SELECT * FROM products WHERE price NOT BETWEEN 10 AND 20;\n\n//is null\nconst product = await Product.findOne({ where: { description: { isNull: true } } });\n// run this query: SELECT * FROM products WHERE description IS NULL;\n\n//is not null\nconst product = await Product.findOne({ where: { description: { isNotNull: true } } });\n// run this query: SELECT * FROM products WHERE description IS NOT NULL;\n\n//and\nconst product = await Product.findOne({ where: { category: 'electronics', price: { gt: 10 } } });\n// run this query: SELECT * FROM products WHERE category = 'electronics' AND price \u003e 10;\n\nconst product = await Product.findOne({ where: { and: [{ category: 'electronics' }, { price: { gt: 10 } }] } });\n// run this query: SELECT * FROM products WHERE (category = 'electronics' AND price \u003e 10);\n\nconst product = await Product.findOne({ where: { name: { like: '%apple%' }, and: [{ category: 'electronics' }, { price: { gt: 10 } }] } });\n// run this query: SELECT * FROM products WHERE name LIKE '%apple%' AND (category = 'electronics' AND price \u003e 10);\n\n//or\nconst product = await Product.findOne({ where: { or: [{ category: 'electronics' }, { price: { gt: 10 } }] } });\n// run this query: SELECT * FROM products WHERE category = 'electronics' OR price \u003e 10;\n\nconst product = await Product.findOne({ where: { name: { like: '%apple%' }, or: [{ category: 'electronics' }, { price: { gt: 10 } }] } });\n// run this query: SELECT * FROM products WHERE name LIKE '%apple%' AND (category = 'electronics' OR price \u003e 10);\n\n//not\nconst product = await Product.findOne({ where: { not: { category: 'electronics' } } });\n// run this query: SELECT * FROM products WHERE NOT category = 'electronics';\n\nconst product = await Product.findOne({attributes: ['id', 'name', 'price'], where: { not: { category: 'electronics' } }});\n// run this query: SELECT id, name, price FROM products WHERE (NOT category = 'electronics');\n```\n\nHere is a table for the LIKE operators in the where clause:\n\n| Operator | Description |\n| --- | --- |\n| `%apple%` | Finds any values that have \"apple\" in any position |\n| `apple%` | Finds any values that start with \"apple\" |\n| `%apple` | Finds any values that end with \"apple\" |\n| `_pple` | Finds any values that have \"pple\" in the second position |\n| `a%e` | Finds any values that start with \"a\" and end with \"e\" |\n| `a%o` | Finds any values that start with \"a\" and ends with \"o\" |\n| `a__%` | Finds any values that start with \"a\" and are at least 3 characters in length |\n| `a_%` | Finds any values that start with \"a\" and are at least 2 characters in length |\n| `_r%` | Finds any values that have \"r\" in the second position |\n\n\n### MappifySQL findById Method\n\nThis method finds one record in the database with the specified id.\n\nExample:\n```javascript\nUser.findById(1).then((record) =\u003e {\n    console.log('Fetched record:', record);\n}).catch((err) =\u003e {\n    console.error(err);\n});\n```\n\n### MappifySQL findAll Method\n\nThis method finds all records in the database that match the specified conditions. The `options` parameter is an object that can contain the following properties:\n\n- `where`: An object specifying the conditions for the query. \n- `exclude`: An array of column names to exclude from the result.\n- `attributes`:An array of column names to include in the result. Default is ['*'] which selects all\n- `limit`: The maximum number of records to return.\n- `offset`: The number of records to skip before starting to return records.\n- `order`: A string specifying the order in which to return the records.\n- `group`: A string specifying the column to group the records by. (column_name ASC/DESC);\nExample:\n```javascript\n// Fetch all products from the database\nconst products = await Product.findAll();\n//run this query: SELECT * FROM products;\n\n// Fetch all products with specific properties\nconst products = await Product.findAll(attributes: ['id', 'name', 'price']);\n//run this query: SELECT id, name, price FROM products;\n\n// Fetch all products and exclude specific properties\nconst products = await Product.findAll(exclude: ['description']);\n\n// Fetch the first 10 products\nconst products = await Product.findAll({ limit: 10 });\n//run this query: SELECT * FROM products LIMIT 10;\n\n// Fetch the second set of 10 products\nconst products = await Product.findAll({ limit: 10, offset: 2 });\n//run this query: SELECT * FROM products LIMIT 10 OFFSET 2;\n\n/* \noffset: 2 will skip the first 10 records and return the next 10 records.\nThis is particularly useful for implementing pagination. The offset can be set dynamically like so: offset: req.query.page\n*/\n\n// Fetch products with the 'electronics' category\nconst products = await Product.findAll({ where: { category: 'electronics' } });\n//run this query: SELECT * FROM products WHERE category = 'electronics';\n\n// Fetch products with the 'electronics' category and exclude the 'description' column from the result\nconst products = await Product.findAll({ where: { category: 'electronics' }, exclude: ['description'] });\n\n// Fetch the total number of products for each category\nconst products = await Product.findAll({ attributes: ['category', 'COUNT(*) AS total'], group: 'category' });\n//run this query: SELECT category, COUNT(*) AS total FROM products GROUP BY category;\n\n// Fetch all products grouped by category and ordered by price in descending order\t\nconst products = await Product.findAll({ group: 'category', order: 'price DESC' });\n//run this query: SELECT * FROM products GROUP BY category ORDER BY price DESC;\n\n//Fetch records using operations\n\n// Equal to\nconst products = await Product.findAll({ where: { price: { eq: 1000 } } });\n// run this query: SELECT * FROM products WHERE price = 1000;\n\n// Greater than\nconst products = await Product.findAll({ where: { price: { gt: 1000 } } });\n// run this query: SELECT * FROM products WHERE price \u003e 1000;\n\n// Less than\nconst products = await Product.findAll({ where: { price: { lt: 1000 } } });\n// run this query: SELECT * FROM products WHERE price \u003c 1000;\n\n// Greater than or equal to\nconst products = await Product.findAll({ where: { price: { gte: 1000 } } });\n// run this query: SELECT * FROM products WHERE price \u003e= 1000;\n\n// Less than or equal to\nconst products = await Product.findAll({ where: { price: { lte: 1000 } } });\n// run this query: SELECT * FROM products WHERE price \u003c= 1000;\n\n// Not equal to\nconst products = await Product.findAll({ where: { price: { ne: 1000 } } });\n// run this query: SELECT * FROM products WHERE price \u003c\u003e 1000;\n\n//greater than and less than\nconst products = await Product.findAll({ where: { price: { gt: 500, lt: 1000 } } });\n// run this query: SELECT * FROM products WHERE price \u003e 500 AND price \u003c 1000;\n\n//like\nconst products = await Product.findAll({ where: { name: { like: '%apple%' } } });\n// run this query: SELECT * FROM products WHERE name LIKE '%apple%';\n\n//not like\nconst products = await Product.findAll({ where: { name: { notLike: '%apple%' } } });\n// run this query: SELECT * FROM products WHERE name NOT LIKE '%apple%';\n\n//in\nconst products = await Product.findAll({ where: { category: { in: ['electronics', 'clothing'] } } });\n// run this query: SELECT * FROM products WHERE category IN ('electronics', 'clothing');\n\n//not in\nconst products = await Product.findAll({ where: { category: { notIn: ['electronics', 'clothing'] } } });\n// run this query: SELECT * FROM products WHERE category NOT IN ('electronics', 'clothing');\n\n//between\nconst products = await Product.findAll({ where: { price: { between: [500, 1000] } } });\n// run this query: SELECT * FROM products WHERE price BETWEEN 500 AND 1000;\n\n//not between\nconst products = await Product.findAll({ where: { price: { notBetween: [500, 1000] } } });\n// run this query: SELECT * FROM products WHERE price NOT BETWEEN 500 AND 1000;\n\n//is null\nconst products = await Product.findAll({ where: { description: { isNull: true } } });\n// run this query: SELECT * FROM products WHERE description IS NULL;\n\n//is not null\nconst users = await User.findAll({ where: { is_subscribed: { isNotNull: true } } });\n// run this query: SELECT * FROM users WHERE is_subscribed IS NOT NULL;\n\n//and\nconst products = await Product.findAll({ where: { category: 'electronics', price: { gt: 500 } } });\n// run this query: SELECT * FROM products WHERE category = 'electronics' AND price \u003e 500;\n\nconst products = await Product.findAll({ where: { and: [{ category: 'electronics' }, { price: { gt: 500 } }] }});\n// run this query: SELECT * FROM products WHERE (category = 'electronics' AND price \u003e 500);\n\nconst products = await Product.findAll({ where: { name: { like: '%apple%' }, and: [{ category: 'electronics' }, { price: { gt: 500 } }] }});\n// run this query: SELECT * FROM products WHERE name LIKE '%apple%' AND (category = 'electronics' AND price \u003e 500);\n\n//or\nconst products = await Product.findAll({ where: { or: [{ category: 'electronics' }, { price: { gt: 500 } }] } });\n// run this query: SELECT * FROM products WHERE category = 'electronics' OR price \u003e 500;\n\nconst products = await Product.findAll({ where: { name: { like: '%apple%' }, or: [{ category: 'electronics' }, { price: { gt: 500 } }] }});\n// run this query: SELECT * FROM products WHERE name LIKE '%apple%' AND (category = 'electronics' OR price \u003e 500);\n\n//not\nconst products = await Product.findAll({ where: { not: { category: 'electronics' } } });\n// run this query: SELECT * FROM products WHERE NOT category = 'electronics';\n\nconst products = await Product.findAll({attributes: ['id', 'name', 'price'], where: { not: { category: 'electronics' } }});\n// run this query: SELECT id, name, price FROM products WHERE (NOT category = 'electronics');\n```\n#### Operations\n| Operation | Description |\n| --- | --- |\n| eq | Equal to `=` |\n| gt | Greater than `\u003e` |\n| lt | Less than `\u003c` |\n| gte | Greater than or equal to `\u003e=` |\n| lte | Less than or equal to `\u003c=` |\n| ne | Not equal to `\u003c\u003e` |\n| like | Like `%value%` |\n| notLike | Not Like `%value%` |\n| in | In `('value1', 'value2')` |\n| notIn | Not In `('value1', 'value2')` |\n| between | Between `value1 AND value2` |\n| notBetween | Not Between `value1 AND value2` |\n| isNull | Is Null |\n| isNotNull | Is Not Null |\n| and | Logical AND |\n| or | Logical OR |\n| not | Logical NOT |\n\n\n### MappifySQL findOrCreate Method\n\nThis method finds one record in the database that matches the specified conditions, or creates a new record if no matching record is found. This function returns a object with two properties: `instance` and `created`. The `instance` property contains the record found or created, and the `created` property is a boolean value indicating whether the record was created or not. This function can be useful implementing a third-party login system where you want to find a user by their email or create a new user if they don't exist.\n\n**Parameters**:\nThere are two parameters for this method:\n- `options`: This is the first parameter and is an object that specifies the conditions for the record to find. It can contain the following properties:\n    - `where`: An object specifying the conditions for the query.  \u003cspan style=\"color: red;\"\u003e **required** \u003c/span\u003e\n    - `exclude`: An array of column names to exclude from the result.\n    - `attributes`: An array of column names to include in the result.\n\n- `defaults`: This is the second parameter and is an object that specifies the values to use when creating a new record. If a record is found, these values are ignored. \n\nExample:\n```javascript\n// Find a user with the email and create a new user if not found\nlet { instance, created } = await User.findOrCreate({ where: { email: 'user@example.com' } }, { name: 'John Doe', picture: 'default.jpg', role: 'user' });\n\nif (created) {\n    console.log('New user created:', instance);\n} else {\n    console.log('User found:', instance);\n}\n\n// Find a user using operations\nlet { instance, created } = await User.findOrCreate({ where: { or: [{ email: 'user@example.com' }, { username: 'user' }] } }, { name: 'John Doe', picture: 'default.jpg', role: 'user' });\n```\n\n### MappifySQL findByIdAndDelete Method\n\nThe `findByIdAndDelete` method finds a single record in the database that matches the specified `id` and deletes it. The parameter is the id of the record to delete.\nIt returns a promise that resolves with a boolean value indicating whether the record was deleted or null if the record was not found.\n\nExample:\n```javascript\nUser.findByIdAndDelete(1).then((deleted) =\u003e {\n    if (deleted) {\n        console.log('Record deleted successfully');\n    } else {\n        console.log('Record not found');\n    }\n}).catch((err) =\u003e {\n    console.error(err);\n});\n```\n\n### MappifySQL findOneAndDelete Method\n\nThis method finds one record in the database that matches the specified conditions and deletes it. \nIt returns a promise that resolves with a boolean value indicating whether the record was deleted or null if the record was not found.\n\n**Parameters**:\nThere are two parameters for this method:\n- `options`: This is the first parameter and is an object that specifies the conditions for the record to find. It can contain the following properties:\n    - `where`: An object specifying the conditions for the query. \u003cspan style=\"color: red;\"\u003e **required** \u003c/span\u003e\n\nExample:\n```javascript\n// you can also use Async/Await\nUser.findOneAndDelete({ where: { email: 'user@example.com' } }).then((deleted) =\u003e {\n    if (deleted) {\n        console.log('Record deleted successfully');\n    } else {\n        console.log('Record not found');\n    }\n}).catch((err) =\u003e {\n    console.error(err);\n});\n```\n\n\n### MappifySQL findOneAndUpdate Method\n\nThis method finds one record in the database that matches the specified conditions and updates it.\nIt returns a promise that resolves with the updated record or null if the record was not found.\n\n**Parameters**:\nThere are two parameters for this method:\n- `options`: This is the first parameter and is an object that specifies the conditions for the record to find. It can contain the following properties:\n    - `where`: An object specifying the conditions for the query. \u003cspan style=\"color: red;\"\u003e **required** \u003c/span\u003e\n    - `exclude`: An array of column names to exclude from the result after the update.\n    - `attributes`: An array of column names to include in the result after the update.\n\n- `data`: This is the second parameter and is an object that specifies the values to update.\n\nExample:\n```javascript\n// you can also use Async/Await\nUser.findOneAndUpdate({ where: { email: 'user@example.com' } }, { name: 'Jane Doe', picture: 'profile.jpg' }).then((user) =\u003e {\n    if (user) {\n        console.log('Record updated successfully');\n    } else {\n        console.log('Record not found');\n    }\n}).catch((err) =\u003e {\n    console.error(err);\n});\n```\n\n### MappifySQL findByIdAndUpdate Method`\n\nThis method finds one record in the database with the specified id and updates it. \nIt returns a promise that resolves with the updated record or null if the record was not found.\n\n**Parameters**:\nThere are two parameters for this method:\n- `id`: This is the first parameter and is the id of the record to update.\n- `data`: This is the second parameter and is an object that specifies the values to update.\n\nExample:\n```javascript\n// you can also use Async/Await\nUser.findByIdAndUpdate(1, { name: 'Jane Doe', picture: 'profile.jpg' }).then((user) =\u003e {\n    if (user) {\n        console.log('Record updated successfully');\n    } else {\n        console.log('Record not found');\n    }\n}).catch((err) =\u003e {\n    console.error(err);\n});\n```\n\n\n### Pagination\n\nYou can implement pagination for large datasets using the limit and offset options in the findAll method. The limit option specifies the maximum number of records to return, and the offset option specifies the number of records i.e. the page number you are on.\n\nExample:\nBy passing the offset dynamically using query parameters, you can fetch the next set of records for each page.\n```javascript\n// Fetch the 10 records for each page\nvar page = req.query.page;\nconst products = await Product.findAll({ limit: 10 , offset: page });\n```\n### Creating a custom function for a model class to perform a database operation\n\nYou can create a custom function for a model class to perform a database operation. This function can be used to encapsulate complex queries or operations that are specific to the model.\n\nExample:\n```javascript\nconst { MappifyModel } = require('mappifysql');\n\nclass Product extends MappifyModel {\n    static async findElectronics() {\n        try {\n            let sql = `SELECT * FROM ${this.tableName} WHERE category = ?`;\n            let results = await this.query(sql, ['electronics']);\n            if (results.length \u003e 0) {\n                return results.map(result =\u003e new this(result));\n            }\n            return [];\n        } catch (err) {\n            throw err;\n        }\n    }\n\n    // create a custom function using functions in the model class\n    static async findElectronics() {\n        try {\n            let results = await this.findAll(attributes: ['id', 'name', 'price'], and: [{ category: 'electronics' }, { price: { between: [500, 1000] } }]);\n            return results;\n        } catch (err) {\n            throw err;\n        }\n    }\n}\nmodule.exports = User;\n\n```\nUsage:\n```javascript\nconst Product = require('path/to/product.js');\n\nProduct.findElectronics().then((products) =\u003e {\n    console.log('Electronics products:', products);\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n```\n\n** Using TypeScript **\n\n```typescript\nconst { MappifyModel } = require('mappifysql');\n\ninterface ProductAttributes {\n    id?: number;\n    name: string;\n    price: number;\n    category: string;\n}\n\nclass Product extends MappifyModel {\n    id?: number;\n    name: string;\n    price: number;\n    category: string;\n\n    constructor(data: ProductAttributes) {\n        super();\n        this.id = data.id;\n        this.name = data.name;\n        this.price = data.price;\n        this.category = data.category;\n    }\n\n\n    // create a custom function using functions in the model class\n    static async findElectronics() {\n        try {\n            let results = await MappifyModel.findAll(attributes: ['id', 'name', 'price'], and: [{ category: 'electronics' }, { price: { between: [500, 1000] } }]);\n            return results;\n        } catch (err) {\n            throw err;\n        }\n    }\n}\n\nexport default Product;\n\n```\nUsage:\n```typescript\nimport Product from 'path/to/product.ts';\n\nProduct.findElectronics().then((products) =\u003e {\n    console.log('Electronics products:', products);\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n```\n\n\n### MappifySQL Transactions\n\nMappifySQL supports transactions, allowing you to execute multiple database operations as a single unit of work. This ensures that all operations are completed successfully or none of them are.\n\n#### Starting a Transaction using the beginTransaction, commit, and rollback methods\n\n```javascript\nconst { query, beginTransaction, commit, rollback } = require('mappifysql');\n\nlet performTransaction = async () =\u003e {\n    try {\n        await beginTransaction();\n        const user = await query('INSERT INTO users SET ?', { name: 'John Doe'});\n        await query('INSERT INTO addresses SET ?', { user_id: user.insertId, address: '123 Main St' });\n        await commit();\n        console.log('Transaction completed successfully');\n    } catch (err) {\n        await rollback();\n        console.error(err);\n    }\n};\n\n//using transaction with the model class\n\nlet performTransaction = async () =\u003e {\n    try {\n        await beginTransaction();\n        let user = new User({ name: 'John Doe' });\n        await user.save();\n        let address = new Address({ user_id: user.id, address: '123 Main St' });\n        await address.save();\n        await commit();\n        console.log('Transaction completed successfully');\n    } catch (err) {\n        await rollback();\n        console.error(err);\n    }\n};\n    \n```\n\n#### Starting a Transaction using the query or connection object directly\n\n\u003cspan style=\"color:red;\"\u003e\u003cb\u003eNote\u003c/b\u003e\u003c/span\u003e: When using the connection object directly, you must release the connection after the transaction is completed in the finally block and you can't use the connection object directly with the model class as it is not exposed to the model class.\n\nIf you wan to use transaction with the model class, you must use the query method or \u003ca href=\"#starting-a-transaction-using-the-begintransaction-commit-and-rollback-method\"\u003eusing beginTransaction commit, and rollback methods from mappifysql\u003c/a\u003e\n\n```javascript\nconst { query, connection } = require('mappifysql');\n\nlet performTransaction = async () =\u003e {\n    try {\n        await query('START TRANSACTION');\n        const user = await query('INSERT INTO users SET ?', { name: 'John Doe'});\n        await query('INSERT INTO addresses SET ?', { user_id: user.insertId, address: '123 Main St' });\n        await query('COMMIT');\n        console.log('Transaction completed successfully');\n    } catch (err) {\n        await query('ROLLBACK');\n        console.error(err);\n    } \n};\n\n// using query function with the Model class\n\nlet performTransaction = async () =\u003e {\n    try {\n        await query('START TRANSACTION');\n        let user = new User({ name: 'John Doe' });\n        await user.save();\n        let address = new Address({ user_id: user.id, address: '123 Main St' });\n        await address.save();\n        await query('COMMIT');\n        console.log('Transaction completed successfully');\n    } catch (err) {\n        await query('ROLLBACK');\n        console.error(err);\n    }\n};\n\n// using the connection object directly\n\n// Note: You can't use the connection object directly with the model class as it is not exposed to the model class and the connection must be released after the transaction is completed in the finally block.\n\n\nlet performTransaction = async () =\u003e {\n    let conn = await connection;\n    try { \n        conn.beginTransaction();\n        const user = conn.query('INSERT INTO users SET ?', { first_name: 'John Doe' });\n        conn.query('INSERT INTO addresses SET ?', { user_id: user.insertId, address: '123 Main St' });\n        conn.commit();\n        console.log('Transaction completed successfully');\n    } catch (err) {\n        conn.rollback();\n        console.error(err);\n    } finally {\n        conn.release();\n    }\n};\n\n\n// using the connection object query method\n\nlet performTransaction = async () =\u003e {\n    let conn = await connection;\n    try { \n        conn.query('START TRANSACTION');\n        const user = conn.query('INSERT INTO users SET ?', { first_name: 'John Doe' });\n        conn.query('INSERT INTO addresses SET ?', { user_id: user.insertId, address: '123 Main St' });\n        conn.query('COMMIT');\n        console.log('Transaction completed successfully');\n    } catch (err) {\n        conn.query('ROLLBACK');\n        console.error(err);\n    } finally {\n        conn.release();\n    }\n};\n\n\n\n```\n\n### Relationships\nMappifySQL allows you to define relationships between your tables, making it easier to fetch related data.\n\n\nThis table provides a quick reference for the methods available in defining relationships between models.\n\n| Method | Description | Parameters | Example |\n| --- | --- | --- | --- |\n| `associations` | Defines the associations that a model has with other models. This method is meant to be overridden in subclasses. | None | `associations() { this.belongsTo(User, { as: 'user', key: 'id', foreignKey: 'user_id' }); }` |\n| `hasOne` | Defines a one-to-one relationship between two models. | `relatedModel`, `options` | `this.hasOne(ShippingAddress, { as: 'shippingAddress', foreignKey: 'order_id' });` |\n| `belongsTo` | Defines a one-to-one relationship where the model belongs to another model. | `relatedModel`, `options` | `this.belongsTo(Order, { as: 'order', key: 'id', foreignKey: 'order_id' });` |\n| `hasMany` | Defines a one-to-many relationship where the model has many instances of another model. | `relatedModel`, `options` | `this.hasMany(User, { as: 'user', foreignKey: 'post_id' });` |\n| `belongsToMany` | Defines a many-to-many relationship between two models. | `relatedModel`, `options` | `this.belongsToMany(Course, { as: 'courses', through: Enrollment, key: 'id', foreignKey: 'student_id', otherKey: 'course_id' });` |\n| `populate` | Fetches the related data for a given relation. | `relation`, `options` (optional) | `await post.populate('user');` |\n| `attach` | Attaches a new record to the related model and associates it with the current model. | `target`, `relation`, `options` (optional) | `await post.attach(post, 'posts');` |\n\n\n\nThis table provides a quick reference for the options available in defining relationships between models.\n\n| Method        | Key           | Description  |\n| ------------- |:-------------:| -----:|\n| hasOne        | as            | The alias for the association. |\n|               | foreignKey    | The foreign key in this model. |\n| belongsTo     | as            | The alias for the association. |\n|               | key           | The primary key in the related model. |\n|               | foreignKey    | The foreign key in this model. |\n| hasMany       | as            | The alias for the association. |\n|               | foreignKey    | The foreign key in the related model. |\n| belongsToMany | as            | The alias for the association. |\n|               | through       | The \"join\" table model that connects the two models. |\n|               | key           | The primary key in the related model. |\n|               | foreignKey    | The foreign key in through model for this model. |\n|               | otherKey      | The foreign key in through model for the related model. |\n| populate      | relation      | The name of the relation to fetch. |\n|               | attributes    | The columns to include in the result. |\n|               | exclude       | The columns to exclude from the result. |\n| attach        | target        | The record to attach to the related model. |\n|               | relation      | The name of the relation to attach to. |\n|               | attributes    | The columns to include in the result. |\n|               | exclude       | The columns to exclude from the result. |\n\n\nPlease note that `attributes` and `exclude` keys in the `populate` and `attach` methods are optional and can be used to specify the columns to include or exclude from the result.\n\n\u003cspan style=\"color:red;\"\u003e\u003cb\u003eNote\u003c/b\u003e\u003c/span\u003e: The `populate` method is used to fetch the related data for a given relation. The `attach` method is used to attach a new record to the related model and associate it with the current model and it can only be used with the `hasOne` and `hasMany` relationships.\n\n#### Defining Relationships\n\n#### One-to-One Relationship\n\nIn a one-to-one relationship, each record in one table is associated with exactly one record in another table. For example, each order has exactly one shipping address, and each shipping address belongs to exactly one order.\n\n\n```javascript\nconst { MappifyModel } = require('mappifysql');\nconst ShippingAddress = require('path/to/ShippingAddress');\n\nclass Order extends MappifyModel {\n    associations() {\n        this.hasOne(ShippingAddress, {\n            as: 'shippingAddress',\n            foreignKey: 'order_id'\n        });\n    }\n}\n\nmodule.exports = Order;\n\n```\n\n\nUsage:\n```javascript\nconst Order = require('path/to/Order');\n\nOrder.findOne({ where: { id: 1 }}).then(async (order) =\u003e {\n    if (order) {\n        await order.populate('shippingAddress', {exclude: ['created_at', 'updated_at']}).then((order) =\u003e {\n            console.log('Order with shipping address:', order);\n        });\n    }\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\nOrder.findAll().then(async (orders) =\u003e {\n    await Promise.all(orders.map(async (order) =\u003e {\n    await order.populate('shippingAddress', {exclude: ['created_at', 'updated_at']});\n    }));\nconsole.log('Orders with shipping addresses:', orders);\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n\n```\n\n```typescript\nimport { MappifyModel } from 'mappifysql';\nimport Order from 'path/to/Order';\n\ninterface ShippingAddressAttributes {\n    id?: number;\n    address: string;\n    city: string;\n    state: string;\n}\n\nclass ShippingAddress extends MappifyModel {\n    id?: number;\n    address: string;\n    city: string;\n\n    constructor(data: ShippingAddressAttributes) {\n        super();\n        this.id = data.id;\n        this.address = data.address;\n        this.city = data.city;\n    }\n    \n\n    associations() {\n        this.belongsTo(Order, {\n            as: 'order',\n            key: 'id'\n            foreignKey: 'order_id'\n        });\n    }\n}\n\nexport default ShippingAddress;\n```\n\nUsage:\n```typescript\nimport ShippingAddress from 'path/to/ShippingAddress';\n\nShippingAddress.findByOne({ where: { id: 1 }}).then(async(shippingAddress) =\u003e {\n   await shippingAddress.populate('order', {attributes: ['id', 'total']}).then((shippingAddress) =\u003e {\n        console.log('Shipping address with order:', shippingAddress);\n    });\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\nShippingAddress.findAll().then(async (shippingAddresses) =\u003e {\n    await Promise.all(shippingAddresses.map(async (shippingAddress) =\u003e {\n    await shippingAddress.populate('order', {attributes: ['id', 'total']});\n    }));\nconsole.log('Shipping addresses with orders:', shippingAddresses);\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n```\n\n** Using `attach` method **\n\n```javascript\nconst Order = require('path/to/Order');\nconst ShippingAddress = require('path/to/ShippingAddress');\n\nlet createShippingAddress = async () =\u003e {\n    var order = await Order.findById(1);\n    var shippingAddress = new ShippingAddress({ address: '123 Main St', city: 'New York', state: 'NY' });\n    await order.attach(shippingAddress, 'shippingAddress', { exclude: ['created_at', 'updated_at'] });\n    console.log('Shipping address created:', shippingAddress);\n};\n\ncreateShippingAddress();\n\n```\n\n```typescript\nimport Order from 'path/to/Order';\nimport ShippingAddress from 'path/to/ShippingAddress';\n\nlet createShippingAddress = async () =\u003e {\n    var order = await Order.findOne({ where: { id: 1 } });\n    var shippingAddress = new ShippingAddress({ address: '123 Main St', city: 'New York', state: 'NY' });\n    await order.attach(shippingAddress, 'shippingAddress');\n    console.log('Shipping address created:', shippingAddress);\n};\n\ncreateShippingAddress();\n\n```\n\n#### One-to-Many Relationship\n\nIn a one-to-many relationship, each record in one table is associated with one or more records in another table. For example, each user can have multiple orders, but each order belongs to exactly one user.\n\n```javascript\nconst { MappifyModel } = require('mappifysql');\nconst Order = require('path/to/Order');\n\nclass User extends MappifyModel {\n    associations() {\n        this.hasMany(Order, {\n            as: 'orders',\n            foreignKey: 'user_id'\n        });\n    }\n}\n\nmodule.exports = User;\n\n```\n\nUsage:\n```javascript\nconst User = require('path/to/User');\n\nlet fetchUserOrders = async () =\u003e {\n    var user = await User.findOne({ where: { id: 1 } });\n    await user.populate('orders', { exclude: ['created_at', 'updated_at'] });\n    console.log('User with orders:', user);\n};\n\nfetchUserOrders();\n\n```\n\n```typescript\n\nimport { MappifyModel } from 'mappifysql';\nimport Order from 'path/to/Order';\n\ninterface OrderAttributes {\n    id?: number;\n    total: number;\n}\n\n\nclass Order extends MappifyModel {\n    id?: number;\n    total: number;\n\n    constructor(data: OrderAttributes) {\n        super();\n        this.id = data.id;\n        this.total = data.total;\n    }\n\n\n    associations() {\n        this.belongsTo(User, {\n            as: 'user',\n            key: 'id'\n            foreignKey: 'user_id'\n        });\n    }\n}\n\nexport default User;\n\n```\n\nUsage:\n```typescript\nimport Order from 'path/to/Order';\n\nlet fetchOrderUser = async () =\u003e {\n    var order = await Order.findOne({ where: { id: 1 } });\n    await order.populate('user', {attributes: ['id', 'name']});\n    console.log('Order with user:', order);\n};\n\nfetchOrderUser();\n\n```\n\n** Using `attach` method **\n\n```javascript\nconst User = require('path/to/User');\nconst Order = require('path/to/Order');\n\nlet createOrder = async () =\u003e {\n    var user = await User.findById(1);\n    var order = new Order({ total: 1000 });\n    await user.attach(order, 'orders');\n    console.log('Order created:', order);\n};\n\ncreateOrder();\n\n```\n\n```typescript\nimport User from 'path/to/User';\nimport Order from 'path/to/Order';\n\nlet createOrder = async () =\u003e {\n    var user = await User.findOne({ where: { id: 1 } });\n    var order = new Order({ total: 1000 });\n    await user.attach(order, 'orders');\n    console.log('Order created:', order);\n};\n\ncreateOrder();\n\n```\n\n\n#### Many-to-Many Relationship\n\nIn a many-to-many relationship, each record in one table is associated with one or more records in another table, and vice versa. For example, each product can belong to multiple categories, and each category can have multiple products.\n\n\u003cspan style=\"color:red;\"\u003e\u003cb\u003eNote\u003c/b\u003e\u003c/span\u003e: When using the `belongsToMany` method, import the through model at the bottom of the file to avoid circular dependencies.\n\n```javascript\nconst { MappifyModel } = require('mappifysql');\nconst Category = require('path/to/Category');\n\nclass Product extends MappifyModel {\n    associations() {\n        this.belongsToMany(Category, {\n            as: 'categories',\n            through: ProductCategory,\n            key: 'id',\n            foreignKey: 'product_id',\n            otherKey: 'category_id'\n        });\n    }\n}\n\nmodule.exports = Product;\nconst ProductCategory = require('path/to/ProductCategory');\n\n```\nUsage:\n```javascript\nconst Product = require('path/to/Product');\n\nProduct.findOne({ where: { id: 1 }}).then((product) =\u003e {\n    product.populate('categories', { exclude: ['created_at', 'updated_at'] }).then((product) =\u003e {\n        console.log('Product with categories:', product);\n    });\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n```\n\n** Using TypeScript **\n\n```typescript\nimport { MappifyModel } from 'mappifysql';\nimport Product from 'path/to/Product';\n\ninterface CategoryAttributes {\n    id?: number;\n    name: string;\n}\n\nclass Category extends MappifyModel {\n    id?: number;\n    name: string;\n\n    constructor(data: CategoryAttributes) {\n        super();\n        this.id = data.id;\n        this.name = data.name;\n    }\n\n\n    \n    associations() {\n        this.belongsToMany(Product, {\n            as: 'products',\n            through: ProductCategory,\n            key: 'id',\n            foreignKey: 'category_id',\n            otherKey: 'product_id'\n        });\n    }\n}\n\nexport default Category;\nimport ProductCategory from 'path/to/ProductCategory';\n```\n\nUsage:\n```typescript\nimport Category from 'path/to/Category';\n\nCategory.findOne({ where: { id: 1 }}).then((category) =\u003e {\n    category.populate('products', {attributes: ['id', 'name', 'price']}).then((category) =\u003e {\n        console.log('Category with products:', category);\n    });\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n```\n\u003cspan style=\"color:red;\"\u003e\u003cb\u003eNote\u003c/b\u003e\u003c/span\u003e: The model classes can contain many relationships, and you can define as many relationships as needed for your application. Also, if a model has multiple relationships, you can populate them individually for each relationship.\n\nExample:\n```javascript\nconst { MappifyModel } = require('mappifysql');\nconst Student = require('path/to/studentmodel');\n const Course = require('path/to/coursemodel');\n\n\n class Enrollment extends MappifyModel {\n    associations() {\n        this.belongsTo(Student, {\n            as: 'student',\n            key: 'id',\n            foreignKey: 'student_id'\n        });\n        this.belongsTo(Course, {\n            as: 'course',\n            key: 'id',\n            foreignKey: 'course_id'\n        });\n    }\n}\n\nmodule.exports = Enrollment;\n\n```\n\nUsage:\n```javascript\nconst Enrollment = require('path/to/Enrollment');\n\nEnrollment.findOne({ where: { id: 1 }}).then((enrollment) =\u003e {\n    enrollment.populate('student', {attributes: ['id', 'name']}).then(() =\u003e {\n    }).then(() =\u003e {\n        enrollment.populate('course', {attributes: ['id', 'name']}).then(() =\u003e {\n            console.log('Enrollment with student and course:', enrollment);\n        });\n    });\n}).catch((err) =\u003e {\n    console.error(err);\n});\n\n```\n\n```typescript\nimport { MappifyModel } from 'mappifysql';\nimport Student from 'path/to/studentmodel';\nimport Course from 'path/to/coursemodel';\n\ninterface EnrollmentAttributes {\n    id?: number;\n    student_id: number;\n    course_id: number;\n}\n\nclass Enrollment extends MappifyModel {\n    id?: number;\n    student_id: number;\n    course_id: number;\n\n    constructor(data: EnrollmentAttributes) {\n        super();\n        this.id = data.id;\n        this.student_id = data.student_id;\n        this.course_id = data.course_id;\n    }\n\n\n    associations() {\n        this.belongsTo(Student, {\n            as: 'student',\n            key: 'id',\n            foreignKey: 'student_id'\n        });\n        this.belongsTo(Course, {\n            as: 'course',\n            key: 'id',\n            foreignKey: 'course_id'\n        });\n    }\n}\n\nexport default Enrollment;\n\n```\n\nUsage:\n```typescript\nimport Enrollment from 'path/to/Enrollment';\n\nlet enroll = async () =\u003e {\n    var enrollment = await Enrollment.findOne({ where: { id: 1 } });\n    await enrollment.populate('student', {attributes: ['id', 'name']});\n    await enrollment.populate('course', {attributes: ['id', 'name']});\n    console.log('Enrollment with student and course:', enrollment);\n};\n\nenroll();\n\n```\n\n##### Issues\n\nIf you encounter any issues or have any questions, please feel free to open an issue on the GitHub repository. We are always happy to help and improve the library.\n\n\u003c!-- ##### Contributing\n\nIf you would like to contribute to the project, please feel free to fork the repository and submit a pull request. We welcome all contributions and appreciate your help in making the library better. --\u003e\n\n##### License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n\u003c!-- ##### Acknowledgments\n\nWe would like to thank all the contributors to the project and the open-source community for their support and feedback. We appreciate your help in making the library better and more useful for developers. --\u003e\n\n##### References\n\n\u003c!-- - [MappifySQL Documentation]( --\u003e\n\n- [MappifySQL GitHub Repository](https://github.com/Walidadebayo/MappifySQL.git)\n\n- [MappifySQL NPM Package](https://www.npmjs.com/package/mappifysql)\n\n\u003c!-- - [MappifySQL Examples]( --\u003e\n\n- [MappifySQL Issues](https://github.com/Walidadebayo/MappifySQL/issues)\n\n- [MappifySQL License](https://github.com/Walidadebayo/mappifysql/blob/main/LICENSE)\n\n\u003c!-- - [MappifySQL Contributors](https://github.com/Walidadebayo/mappifysql/graphs/contributors) --\u003e\n\n\u003c!-- - [MappifySQL Open Source Community]( --\u003e\n\n\n\u003ca href=\"https://www.buymeacoffee.com/walidadebayo\"\u003e\u003cimg src=\"https://img.buymeacoffee.com/button-api/?text=Buy me a coffee\u0026emoji=\u0026slug=walidadebayo\u0026button_colour=FFDD00\u0026font_colour=000000\u0026font_family=Comic\u0026outline_colour=000000\u0026coffee_colour=ffffff\" /\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwalidadebayo%2Fmappifysql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwalidadebayo%2Fmappifysql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwalidadebayo%2Fmappifysql/lists"}