{"id":15003203,"url":"https://github.com/chriseaton/rhino","last_synced_at":"2025-07-10T12:16:57.921Z","repository":{"id":34408315,"uuid":"170441290","full_name":"chriseaton/rhino","owner":"chriseaton","description":"Rhino is a production-focused Microsoft SQL Server driver for Node.JS that features pooling asynchronous operations, it is a solid alternative to the other popular packages.","archived":false,"fork":false,"pushed_at":"2023-01-10T09:36:30.000Z","size":3123,"stargazers_count":6,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-09-29T14:40:57.452Z","etag":null,"topics":["async","connector","driver","microsoft-sql-server","mssql","node","pooling"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chriseaton.png","metadata":{"files":{"readme":"README.hbs","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}},"created_at":"2019-02-13T04:39:21.000Z","updated_at":"2024-03-04T23:55:32.000Z","dependencies_parsed_at":"2023-01-15T06:54:45.812Z","dependency_job_id":null,"html_url":"https://github.com/chriseaton/rhino","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chriseaton%2Frhino","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chriseaton%2Frhino/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chriseaton%2Frhino/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chriseaton%2Frhino/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chriseaton","download_url":"https://codeload.github.com/chriseaton/rhino/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219856479,"owners_count":16556082,"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":["async","connector","driver","microsoft-sql-server","mssql","node","pooling"],"created_at":"2024-09-24T18:57:00.501Z","updated_at":"2024-10-12T07:23:17.962Z","avatar_url":"https://github.com/chriseaton.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Rhino](./rhino.png)\n\n[![NPM](https://img.shields.io/npm/v/rhino)](https://npmjs.org/package/rhino)\n[![License](https://img.shields.io/npm/l/rhino)](https://npmjs.org/package/rhino)\n[![Downloads](https://img.shields.io/npm/dt/rhino)](https://npmjs.org/package/rhino)\n\n# Rhino\n\nRhino is a tough, production-focused Node.js Microsoft SQL Server driver that incorporates pooling and runs the \nwell-supported [tedious](http://tediousjs.github.io/tedious/) package under\nthe hood, fully utilizing all of it's [available configuration options](http://tediousjs.github.io/tedious/api-connection.html#function_newConnection). \nRhino was built to take the frustration out of running database queries and let you, the developer, focus on running\nqueries and getting reliable, fast, results.\n\nRhino is a solid choice because...\n- It fully implements JSdoc and is tested with [VS Code](https://code.visualstudio.com/) auto-completion.\n- A dependency list so small we can list it here: [tedious](https://github.com/tediousjs/tedious) and [tarn](https://github.com/Vincit/tarn.js).\n- It is a solid, modern, unit-tested implementation built for heavy production use. \n- Employs async/await/Promise functions to let you work asynchronously.\n- Manages connections for you using an internal pool, stop worrying and query!\n- Open-source and accepting pull requests.\n\n# Feature list\n- [x] Automatic connection management.\n- [x] Query execution:\n  - [x] Simple SQL statements.\n  - [x] SQL statements with parameters.\n  - [x] SQL statements using parameter (mapped) objects.\n  - [x] Batch SQL queries (no parameters).\n  - [x] Batch SQL queries returning multiple result-sets.\n  - [x] Stored procedure execution with parameters.\n  - [x] Stored procedures returning multiple result-sets.\n- [x] Bulk loads.\n- [x] Single-Level transactions.\n- [x] Transaction save-point support.\n- [ ] Nested transactions. \n- [ ] Streaming query results.\n\n## Installation\n\n```sh\nnpm i rhino --save\n```\n*or*\n```sh\nyarn add rhino\n```\n\n## Quick Start\n\n```js\n// create the rhino pool.\nconst rhino = require('rhino');\n\n...\nlet db = await rhino.create({\n    //tedious config options, see: https://tediousjs.github.io/tedious/api-connection.html\n    server: 'localhost',\n    authentication: {\n        options: {  \n            userName: \"testuser\",\n            password: \"mypassword\"\n        }\n    },\n    //tarn pooling options\n    pool: {\n        min: 0,\n        max: 10\n    }\n});\n```\n```js\n// run a simple query\nlet results = await db.query('SELECT * FROM dbo.People');\nconsole.log(`Count: ${results.count}`);\nconsole.table(results.rows);\n```\n```js\n// run a parameterized query\nresults = await db\n    .query(`SELECT @valid=IsCustomer \n            FROM contacts \n            WHERE name LIKE @firstName AND account = @number`)\n    .in('firstName', 'John')\n    .in('account', 23494893, Query.TYPE.INT)\n    .out('valid', undefined, 'BIT');\nconsole.log(`Count: ${results.count}`);\nconsole.table(results.rows);\n//use object parameters\nresults = await db.query(\n    'SELECT TOP 10 FROM addresses WHERE street LIKE @street', \n    { street: '% Avenue' }\n);\n```\n```js\n// run queries in a transaction\nlet tx = db.transaction();\ntry {\n    tx.query('INSERT INTO dbo.People (Code, FullName) VALUES (434,\\'John Bircham\\')');\n    tx.query('INSERT INTO dbo.People (Code, FullName) VALUES (@code, @name)', { code: 322, name: 'Amy Smith' });\n    tx.query('DELETE FROM dbo.People WHERE Code = 341');\n    let results = await tx.commit();\n    console.log('Transaction committed.');\n} catch (err) {\n    tx.rollback();\n    console.info('Transaction rolled back.');\n    throw err;\n}\n// run transactions with save-points.\nlet tx = db.transaction();\ntry {\n    tx.query('INSERT INTO dbo.Addresses (Street) VALUES (@st)', { st: '12431 NE Martin St.' });\n    tx.savePoint('mysavepoint');\n    tx.query('INSERT INTO dbo.Addresses (ID) VALUES (1);');\n    let results = await tx.commit();\n} catch (err) {\n    tx.rollback('mysavepoint');\n    console.info('Transaction rolled back to save-point.');\n    throw err;\n}\n```\n```js\n// run a bulk-load\nlet bulk = db.bulk('dbo.Theme', { timeout: 10000 });\nawait bk.column('Name', Query.TYPE.VarChar, { nullable: false, length: 512 });\nawait bk.column('HexCode', Query.TYPE.VarChar, { nullable: false, length: 512 });\nfor (let x = 0; x \u003c 1000; x++) {\n    //add rows\n    bk.add({ Name: `name${x}`, HexCode: `#000${x}${x}${x}` });\n}\nlet result = await bk.execute();\n```\n```js\n...\n// all done, forever!\n// clean up resources\ndb.destroy(); \n```\n\n# API \n\n{{\u003emain}}\n\n# Project Maintenance\n\n## Unit Testing\nUnit-testing this driver requires a Microsoft SQL Server instance running in docker from the `chriseaton/adventureworks` image.\nDue to the fragile nature of the database unit-testing, and to avoid collisions with other users, it's recommended\nto use the process described below ([docker](https://www.docker.com/products/docker-engine) is required).\n\n### 1. Run the container.\nYou need to run the `chriseaton/adventureworks` container from the built image. This will spin up the server and run the install \nscript. It is usually ideal to run the container in daemon mode (`-d`), as the container will stay alive until stopped.\n\n```\ndocker run -p 1433:1433 -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=YourStr0ng_PasswordHERE' --name rhino_test -d chriseaton/adventureworks:latest\n```\n\nWhen run using the command above, the docker server will be accessible on localhost port 1433. To kill the container, run:\n```\ndocker rm -f rhino_test\n```\n\n### 2. Setup testing environment.\nConfigure a `.env` file in the root project folder and define the variables for connecting:\n```\nRHINO_MSSQL_HOST = localhost\nRHINO_MSSQL_USER = sa\nRHINO_MSSQL_PASSWORD = YourStr0ng_PasswordHERE\nRHINO_MSSQL_DATABASE = AdventureWorks\n```\n\nYou should repleace the `RHINO_MSSQL_PASSWORD` password with your own uniquely generated strong password used in the `docker run` command from step 1.\n\n### 3. Run tests.\nIf you just executed the `docker run` command in step 1, you may need to wait a few seconds for the container to finish loading.\n\u003e You can check if loading is complete when the `docker logs rhino_test | grep 'Server is ready.'` returns a ready message.\nNow that the test database server is up and running, you can run the Rhino unit-tests:\n\n```\nnpm test\n```\n\n#### Troubleshooting\nYou can view the container logs to see the output from the server, including any runtime failures.\n\n##### Show the running containers:\n```\ndocker ls\n```\n\n##### Show the output from a container:\n```\ndocker logs {container ID or Name here}\n```\n\n## Updating the API/Readme\nThe `README.md` file in this project is generated using the `js-to-markdown` package, essentially merging the JSdoc \noutput into the `README.hbs` handlebars template file.\n\nTo rebuild the `README.md` file, simply run:\n```\nnpm run doc\n```\n\n## Issues / Requests / Contributing\nPlease utilize the [issues](https://github.com/chriseaton/rhino/issues) on the project to report a problem or provide feedback. Additional contributors are welcome.\n\n1. Make sure the issue is with `rhino` and *not* the [tedious](https://github.com/tediousjs/tedious/issues) package. \n2. Gather details, your node and `rhino` version.\n3. Provide as much information as possible, including steps to reporoduce the issue. Or better yet, provide a resolution with a merge request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchriseaton%2Frhino","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchriseaton%2Frhino","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchriseaton%2Frhino/lists"}