{"id":15659858,"url":"https://github.com/sivchari/db_wrapper","last_synced_at":"2025-05-05T19:54:11.418Z","repository":{"id":45273167,"uuid":"363307389","full_name":"sivchari/db_wrapper","owner":"sivchari","description":"db provides more faster methods than std libs","archived":false,"fork":false,"pushed_at":"2021-12-25T23:41:35.000Z","size":107522,"stargazers_count":21,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-30T23:12:21.070Z","etag":null,"topics":["database","mysql","nim","nim-lang","nim-language","nimble","postgresql","sqlite","sqlite3"],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sivchari.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-01T02:38:24.000Z","updated_at":"2024-10-22T02:55:49.000Z","dependencies_parsed_at":"2022-08-31T02:00:39.240Z","dependency_job_id":null,"html_url":"https://github.com/sivchari/db_wrapper","commit_stats":null,"previous_names":["sivchari/database"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sivchari%2Fdb_wrapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sivchari%2Fdb_wrapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sivchari%2Fdb_wrapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sivchari%2Fdb_wrapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sivchari","download_url":"https://codeload.github.com/sivchari/db_wrapper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252567568,"owners_count":21769257,"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":["database","mysql","nim","nim-lang","nim-language","nimble","postgresql","sqlite","sqlite3"],"created_at":"2024-10-03T13:19:26.337Z","updated_at":"2025-05-05T19:54:11.390Z","avatar_url":"https://github.com/sivchari.png","language":"Nim","readme":"# db_wrapper\n\n[![nim_test](https://github.com/sivchari/db_wrapper/actions/workflows/nim_test.yml/badge.svg)](https://github.com/sivchari/db_wrapper/actions/workflows/nim_test.yml)\n[![sivchari\u003e](https://circleci.com/gh/sivchari/db_wrapper.svg?style=svg)](https://github.com/sivchari/db)\n\ndb_wrapper provides intuitive DB methods.  \nJust by using this library, you can use MySQL, PostgreSQL, and SQLite.  \nBy using connection pooling, parallel DB processing can be done at high speed.\n\n## Performance using spwan or parallel\n![MySQL Parallel Benchmark](img/parallel_query.png)\n\n### db_mysql (Asynchronous because there is no connection pool)\n\u003e 31.146314212 sec\n\n### db_wrapper (Parallel)\n\u003e 12.02923 sec\n\n## Installation\n```shell\nnimble install https://github.com/sivchari/db_wrapper\nnimble install db_wrapper\n```\n\n## Example\n### MySQL\n```nim\nimport db_wrapper\n\nlet db = open(MySQL, \"database\", \"user\", \"Password!\", \"127.0.0.1\", \"3306\", 10)\necho db.ping\n\necho \"insert\"\ndiscard db.query(\"INSERT INTO sample(id, age, name) VALUES(?, ?, ?)\", 1, 10, \"New Nim\")\n\necho \"select\"\nlet row1 = db.query(\"SELECT * FROM sample WHERE id = ?\", 1)\nlet row2 = db.prepare(\"SELECT * FROM sample WHERE id = ?\").query(1)\n\necho row1.all\necho row1[0]\necho row1.columnTypes\necho row1.columnNames\n\necho row2.all\necho row2[0]\necho row2.columnTypes\necho row2.columnNames\n\necho \"update\"\nlet stmt1 = db.prepare(\"UPDATE sample SET name = ? WHERE id = ?\")\ndiscard stmt1.exec(\"Change Nim\", 1)\n\necho \"delete\"\nlet stmt2 = db.prepare(\"DELETE FROM sample WHERE id = ?\")\ndiscard stmt2.exec(1)\n\ndb.transaction:\n  let stmt3 = db.prepare(\"UPDATE sample SET name = ? WHERE id = ?\")\n  discard stmt3.exec(\"Rollback Nim\", 1)\n  raise newException(Exception, \"rollback\")\n\ndiscard db.close\n```\n\n### PostgreSQL\n```nim\nimport db_wrapper\n\nlet db = open(PostgreSQL, \"database\", \"user\", \"Password!\", \"127.0.0.1\", \"5432\", 1)\necho db.ping\n\necho \"insert\"\ndiscard db.query(\"INSERT INTO sample(id, age, name) VALUES($1, $2, $3)\", 1, 10, \"New Nim\")\n\necho \"select\"\nlet row1 = db.query(\"SELECT * FROM sample WHERE id = $1\", 1)\nlet row2 = db.prepare(\"SELECT * FROM sample WHERE id = $1\").query(1)\n\necho row1.all\necho row1[0]\necho row1.columnTypes\necho row1.columnNames\n\necho row2.all\necho row2[0]\necho row2.columnTypes\necho row2.columnNames\n\necho \"update\"\nlet stmt1 = db.prepare(\"UPDATE sample SET name = $1 WHERE id = $2\")\ndiscard stmt1.exec(\"Change Nim\", 1)\n\necho \"delete\"\nlet stmt2 = db.prepare(\"DELETE FROM sample WHERE id = $1\")\ndiscard stmt2.exec(1)\n\ndb.transaction:\n  let stmt3 = db.prepare(\"UPDATE sample SET name = $1 WHERE id = $2\")\n  discard stmt3.exec(\"Rollback Nim\", 1)\n  raise newException(Exception, \"rollback\")\n\ndiscard db.close\n```\n\n### SQLite\n```nim\nimport db_wrapper\n\nlet db = open(SQLite3, \"sample.sqlite3\")\necho db.ping\n\nlet cmd = \"\"\"CREATE TABLE IF NOT EXISTS sample (\n     id INT\n    ,age INT\n    ,name VARCHAR\n)\"\"\"\n\ndiscard db.query(cmd)\n\necho \"insert\"\ndiscard db.query(\"INSERT INTO sample(id, age, name) VALUES(?, ?, ?)\", 1, 10, \"New Nim\")\n\necho \"select\"\nlet row1 = db.query(\"SELECT * FROM sample WHERE id = ?\", 1)\nlet row2 = db.prepare(\"SELECT * FROM sample WHERE id = ?\").query(1)\n\necho row1.all\necho row1[0]\necho row1.columnTypes\necho row1.columnNames\n\necho row2.all\necho row2[0]\necho row2.columnTypes\necho row2.columnNames\n\necho \"update\"\nlet stmt1 = db.prepare(\"UPDATE sample SET name = ? WHERE id = ?\")\ndiscard stmt1.exec(\"Change Nim\", 1)\n\necho \"delete\"\nlet stmt2 = db.prepare(\"DELETE FROM sample WHERE id = ?\")\ndiscard stmt2.exec(1)\n\ndiscard db.close\n```\n\n## Cross Compile\n\n### Mac\n```shell\nGOARCH=arm64 CGO_ENABLED=1 go build -buildmode=c-shared -o sql_arm64.so *.go\nGOARCH=amd64 CGO_ENABLED=1 go build -buildmode=c-shared -o sql_amd64.so *.go\n```\n\n### Linux\n```shell\ndocker-compose up --build -d linux-compile\ndocker-compose exec linux-compile bash\ncd src/database-resource/\ngo get golang.org/dl/go1.16\ngo1.16 download\nGOOS=linux GOARCH=amd64 CGO_ENABLED=1 go1.16 build -buildmode=c-shared -o sql_linux_amd64.so *.go\n```\n\n### Windows\n```shell\ndocker-compose up --build -d windows-compile\ndocker-compose exec windows-compile bash\ncd src/database-resource/\napt -y update\napt -y install gcc-mingw-w64\napt -y install binutils-mingw-w64\nGOOS=windows GOARCH=amd64 CGO_ENABLED=1 CXX=x86_64-w64-mingw32-g++ CC=x86_64-w64-mingw32-gcc go build -buildmode=c-shared -o sql_windows_amd64.dll *.go\n```\n\n## Benchmark\n\nThere is an official database library for Nim, but it does not implement connection pooling.\nHowever, this library (db_wrapper) allows connection pooling to be set at connection time.\nThis library (db_wrapper) implicitly sets the same value as the connection pool as idle connection when connecting.\n\n`There is a 9 second difference in performance between db_mysql and db_mysql for 150,000 queries issued.`\n\nHere is a benchmark of the official db_mysql and 15000 queries and 150000 run with async\n\n## Loop 15000\n![MySQL 15000 Benchmark](img/mysql_loop_15000.png)\n\n### db_mysql\n\u003e 3.263424069 sec\n\n### db_wrapper\n\u003e 2.4392 sec\n\nThe reason why only the standard library calls sleep in the 150000 loop is because the standard library does not support concurrency and will execute another query before the query is completed.\n\nHere is the error message\n\n```shell\ncommands out of sync; you can't run this command now\n```\n\n## Loop 150000\n![MySQL 150000 Benchmark](img/mysql_loop_150000.png)\n\n### db_mysql\n\u003e 30.681650918 sec\n\n### db_wrapper\n\u003e 23.312019 sec\n\n## If you put async in both cases\n![MySQL async 150000 Benchmark](img/async_mysql_loop_150000.png)\n\n### db_mysql\n\u003e 38.237305311 sec\n\n### db_wrapper\n\u003e 29.214669 sec\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsivchari%2Fdb_wrapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsivchari%2Fdb_wrapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsivchari%2Fdb_wrapper/lists"}